diff options
Diffstat (limited to 'dev')
50 files changed, 2410 insertions, 2946 deletions
diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc index 6ca5e3a06..2e46f7be1 100644 --- a/dev/alpha_console.cc +++ b/dev/alpha_console.cc @@ -41,36 +41,25 @@ #include "cpu/base.hh" #include "cpu/exec_context.hh" #include "dev/alpha_console.hh" +#include "dev/platform.hh" #include "dev/simconsole.hh" #include "dev/simple_disk.hh" -#include "dev/tsunami_io.hh" -#include "mem/bus/bus.hh" -#include "mem/bus/pio_interface.hh" -#include "mem/bus/pio_interface_impl.hh" -#include "mem/functional/memory_control.hh" -#include "mem/functional/physical.hh" +#include "mem/physical.hh" #include "sim/builder.hh" #include "sim/sim_object.hh" using namespace std; using namespace AlphaISA; -AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d, - AlphaSystem *s, BaseCPU *c, Platform *p, - MemoryController *mmu, Addr a, - HierParams *hier, Bus *pio_bus) - : PioDevice(name, p), disk(d), console(cons), system(s), cpu(c), addr(a) +AlphaConsole::AlphaConsole(Params *p) + : BasicPioDevice(p), disk(p->disk), + console(params()->cons), system(params()->alpha_sys), cpu(params()->cpu) { - mmu->add_child(this, RangeSize(addr, size)); - if (pio_bus) { - pioInterface = newPioInterface(name + ".pio", hier, pio_bus, this, - &AlphaConsole::cacheAccess); - pioInterface->addAddrRange(RangeSize(addr, size)); - } + pioSize = sizeof(struct AlphaAccess); - alphaAccess = new Access; - alphaAccess->last_offset = size - 1; + alphaAccess = new Access(); + alphaAccess->last_offset = pioSize - 1; alphaAccess->version = ALPHA_ACCESS_VERSION; alphaAccess->diskUnit = 1; @@ -83,130 +72,133 @@ AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d, alphaAccess->inputChar = 0; bzero(alphaAccess->cpuStack, sizeof(alphaAccess->cpuStack)); - system->setAlphaAccess(addr); } void AlphaConsole::startup() { + system->setAlphaAccess(pioAddr); alphaAccess->numCPUs = system->getNumCPUs(); alphaAccess->kernStart = system->getKernelStart(); alphaAccess->kernEnd = system->getKernelEnd(); alphaAccess->entryPoint = system->getKernelEntry(); alphaAccess->mem_size = system->physmem->size(); alphaAccess->cpuClock = cpu->frequency() / 1000000; // In MHz - alphaAccess->intrClockFrequency = platform->intrFrequency(); + alphaAccess->intrClockFrequency = params()->platform->intrFrequency(); } -Fault -AlphaConsole::read(MemReqPtr &req, uint8_t *data) +Tick +AlphaConsole::read(Packet &pkt) { - memset(data, 0, req->size); - Addr daddr = req->paddr - (addr & EV5::PAddrImplMask); + /** XXX Do we want to push the addr munging to a bus brige or something? So + * the device has it's physical address and then the bridge adds on whatever + * machine dependent address swizzle is required? + */ + + assert(pkt.result == Unknown); + assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); - switch (req->size) + pkt.time += pioDelay; + Addr daddr = pkt.addr - pioAddr; + + pkt.allocate(); + + switch (pkt.size) { case sizeof(uint32_t): - DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, - *(uint32_t*)data); switch (daddr) { case offsetof(AlphaAccess, last_offset): - *(uint32_t*)data = alphaAccess->last_offset; + pkt.set(alphaAccess->last_offset); break; case offsetof(AlphaAccess, version): - *(uint32_t*)data = alphaAccess->version; + pkt.set(alphaAccess->version); break; case offsetof(AlphaAccess, numCPUs): - *(uint32_t*)data = alphaAccess->numCPUs; + pkt.set(alphaAccess->numCPUs); break; case offsetof(AlphaAccess, intrClockFrequency): - *(uint32_t*)data = alphaAccess->intrClockFrequency; + pkt.set(alphaAccess->intrClockFrequency); break; default: - // Old console code read in everyting as a 32bit int - *(uint32_t*)data = *(uint32_t*)(consoleData + daddr); - + /* Old console code read in everyting as a 32bit int + * we now break that for better error checking. + */ + pkt.result = BadAddress; } + DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, + pkt.get<uint32_t>()); break; case sizeof(uint64_t): - DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, - *(uint64_t*)data); switch (daddr) { case offsetof(AlphaAccess, inputChar): - *(uint64_t*)data = console->console_in(); + pkt.set(console->console_in()); break; case offsetof(AlphaAccess, cpuClock): - *(uint64_t*)data = alphaAccess->cpuClock; + pkt.set(alphaAccess->cpuClock); break; case offsetof(AlphaAccess, mem_size): - *(uint64_t*)data = alphaAccess->mem_size; + pkt.set(alphaAccess->mem_size); break; case offsetof(AlphaAccess, kernStart): - *(uint64_t*)data = alphaAccess->kernStart; + pkt.set(alphaAccess->kernStart); break; case offsetof(AlphaAccess, kernEnd): - *(uint64_t*)data = alphaAccess->kernEnd; + pkt.set(alphaAccess->kernEnd); break; case offsetof(AlphaAccess, entryPoint): - *(uint64_t*)data = alphaAccess->entryPoint; + pkt.set(alphaAccess->entryPoint); break; case offsetof(AlphaAccess, diskUnit): - *(uint64_t*)data = alphaAccess->diskUnit; + pkt.set(alphaAccess->diskUnit); break; case offsetof(AlphaAccess, diskCount): - *(uint64_t*)data = alphaAccess->diskCount; + pkt.set(alphaAccess->diskCount); break; case offsetof(AlphaAccess, diskPAddr): - *(uint64_t*)data = alphaAccess->diskPAddr; + pkt.set(alphaAccess->diskPAddr); break; case offsetof(AlphaAccess, diskBlock): - *(uint64_t*)data = alphaAccess->diskBlock; + pkt.set(alphaAccess->diskBlock); break; case offsetof(AlphaAccess, diskOperation): - *(uint64_t*)data = alphaAccess->diskOperation; + pkt.set(alphaAccess->diskOperation); break; case offsetof(AlphaAccess, outputChar): - *(uint64_t*)data = alphaAccess->outputChar; + pkt.set(alphaAccess->outputChar); break; default: int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) / sizeof(alphaAccess->cpuStack[0]); if (cpunum >= 0 && cpunum < 64) - *(uint64_t*)data = alphaAccess->cpuStack[cpunum]; + pkt.set(alphaAccess->cpuStack[cpunum]); else panic("Unknown 64bit access, %#x\n", daddr); } + DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, + pkt.get<uint64_t>()); break; default: - return genMachineCheckFault(); + pkt.result = BadAddress; } - - return NoFault; + if (pkt.result == Unknown) pkt.result = Success; + return pioDelay; } -Fault -AlphaConsole::write(MemReqPtr &req, const uint8_t *data) +Tick +AlphaConsole::write(Packet &pkt) { - uint64_t val; - - switch (req->size) { - case sizeof(uint32_t): - val = *(uint32_t *)data; - break; + pkt.time += pioDelay; - case sizeof(uint64_t): - val = *(uint64_t *)data; - break; - default: - return genMachineCheckFault(); - } + assert(pkt.result == Unknown); + assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); + Addr daddr = pkt.addr - pioAddr; - Addr daddr = req->paddr - (addr & EV5::PAddrImplMask); - ExecContext *other_xc; + uint64_t val = pkt.get<uint64_t>(); + assert(pkt.size == sizeof(uint64_t)); switch (daddr) { case offsetof(AlphaAccess, diskUnit): @@ -238,9 +230,6 @@ AlphaConsole::write(MemReqPtr &req, const uint8_t *data) console->out((char)(val & 0xff)); break; - other_xc->activate(); //Start the cpu - break; - default: int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) / sizeof(alphaAccess->cpuStack[0]); @@ -252,13 +241,9 @@ AlphaConsole::write(MemReqPtr &req, const uint8_t *data) panic("Unknown 64bit access, %#x\n", daddr); } - return NoFault; -} + pkt.result = Success; -Tick -AlphaConsole::cacheAccess(MemReqPtr &req) -{ - return curTick + 1000; + return pioDelay; } void @@ -321,14 +306,11 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) SimObjectParam<SimConsole *> sim_console; SimObjectParam<SimpleDisk *> disk; - SimObjectParam<MemoryController *> mmu; - Param<Addr> addr; + Param<Addr> pio_addr; SimObjectParam<AlphaSystem *> system; SimObjectParam<BaseCPU *> cpu; SimObjectParam<Platform *> platform; - SimObjectParam<Bus*> pio_bus; Param<Tick> pio_latency; - SimObjectParam<HierParams *> hier; END_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) @@ -336,21 +318,27 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaConsole) INIT_PARAM(sim_console, "The Simulator Console"), INIT_PARAM(disk, "Simple Disk"), - INIT_PARAM(mmu, "Memory Controller"), - INIT_PARAM(addr, "Device Address"), + INIT_PARAM(pio_addr, "Device Address"), INIT_PARAM(system, "system object"), INIT_PARAM(cpu, "Processor"), INIT_PARAM(platform, "platform"), - INIT_PARAM(pio_bus, "The IO Bus to attach to"), - INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000), - INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) + INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000) END_INIT_SIM_OBJECT_PARAMS(AlphaConsole) CREATE_SIM_OBJECT(AlphaConsole) { - return new AlphaConsole(getInstanceName(), sim_console, disk, - system, cpu, platform, mmu, addr, hier, pio_bus); + AlphaConsole::Params *p = new AlphaConsole::Params; + p->name = getInstanceName(); + p->platform = platform; + p->pio_addr = pio_addr; + p->pio_delay = pio_latency; + p->cons = sim_console; + p->disk = disk; + p->alpha_sys = system; + p->system = system; + p->cpu = cpu; + return new AlphaConsole(p); } REGISTER_SIM_OBJECT("AlphaConsole", AlphaConsole) diff --git a/dev/alpha_console.hh b/dev/alpha_console.hh index f63c6ad7e..05aec5ec1 100644 --- a/dev/alpha_console.hh +++ b/dev/alpha_console.hh @@ -43,7 +43,6 @@ class BaseCPU; class SimConsole; class AlphaSystem; class SimpleDisk; -class MemoryController; /** * Memory mapped interface to the system console. This device @@ -70,7 +69,7 @@ class MemoryController; * primarily used doing boot before the kernel has loaded its device * drivers. */ -class AlphaConsole : public PioDevice +class AlphaConsole : public BasicPioDevice { protected: struct Access : public AlphaAccess @@ -96,32 +95,35 @@ class AlphaConsole : public PioDevice /** a pointer to the CPU boot cpu */ BaseCPU *cpu; - Addr addr; - static const Addr size = sizeof(struct AlphaAccess); + public: + struct Params : public BasicPioDevice::Params + { + SimConsole *cons; + SimpleDisk *disk; + AlphaSystem *alpha_sys; + BaseCPU *cpu; + }; + protected: + const Params *params() const {return (const Params *)_params; } public: + /** Standard Constructor */ - AlphaConsole(const std::string &name, SimConsole *cons, SimpleDisk *d, - AlphaSystem *s, BaseCPU *c, Platform *platform, - MemoryController *mmu, Addr addr, - HierParams *hier, Bus *pio_bus); + AlphaConsole(Params *p); virtual void startup(); /** * memory mapped reads and writes */ - virtual Fault read(MemReqPtr &req, uint8_t *data); - virtual Fault write(MemReqPtr &req, const uint8_t *data); + virtual Tick read(Packet &pkt); + virtual Tick write(Packet &pkt); /** * standard serialization routines for checkpointing */ virtual void serialize(std::ostream &os); virtual void unserialize(Checkpoint *cp, const std::string §ion); - - public: - Tick cacheAccess(MemReqPtr &req); }; #endif // __ALPHA_CONSOLE_HH__ diff --git a/dev/baddev.cc b/dev/baddev.cc index 87d683a5d..dcabdbe0a 100644 --- a/dev/baddev.cc +++ b/dev/baddev.cc @@ -35,82 +35,63 @@ #include <vector> #include "base/trace.hh" -#include "cpu/exec_context.hh" #include "dev/baddev.hh" #include "dev/platform.hh" -#include "mem/bus/bus.hh" -#include "mem/bus/pio_interface.hh" -#include "mem/bus/pio_interface_impl.hh" -#include "mem/functional/memory_control.hh" +#include "mem/port.hh" #include "sim/builder.hh" #include "sim/system.hh" using namespace std; using namespace TheISA; -BadDevice::BadDevice(const string &name, Addr a, MemoryController *mmu, - HierParams *hier, Bus *pio_bus, const string &devicename) - : PioDevice(name, NULL), addr(a), devname(devicename) +BadDevice::BadDevice(Params *p) + : BasicPioDevice(p), devname(p->device_name) { - mmu->add_child(this, RangeSize(addr, size)); - - if (pio_bus) { - pioInterface = newPioInterface(name, hier, pio_bus, this, - &BadDevice::cacheAccess); - pioInterface->addAddrRange(RangeSize(addr, size)); - } - + pioSize = 0xf; } -Fault -BadDevice::read(MemReqPtr &req, uint8_t *data) -{ - - panic("Device %s not imlpmented\n", devname); - return NoFault; -} - -Fault -BadDevice::write(MemReqPtr &req, const uint8_t *data) +Tick +BadDevice::read(Packet &pkt) { panic("Device %s not imlpmented\n", devname); - return NoFault; } Tick -BadDevice::cacheAccess(MemReqPtr &req) +BadDevice::write(Packet &pkt) { - return curTick; + panic("Device %s not imlpmented\n", devname); } BEGIN_DECLARE_SIM_OBJECT_PARAMS(BadDevice) + Param<string> devicename; + Param<Addr> pio_addr; + SimObjectParam<System *> system; SimObjectParam<Platform *> platform; - SimObjectParam<MemoryController *> mmu; - Param<Addr> addr; - SimObjectParam<HierParams *> hier; - SimObjectParam<Bus*> pio_bus; Param<Tick> pio_latency; - Param<string> devicename; END_DECLARE_SIM_OBJECT_PARAMS(BadDevice) BEGIN_INIT_SIM_OBJECT_PARAMS(BadDevice) - INIT_PARAM(platform, "Platform"), - INIT_PARAM(mmu, "Memory Controller"), - INIT_PARAM(addr, "Device Address"), - INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams), - INIT_PARAM_DFLT(pio_bus, "The IO Bus to attach to", NULL), - INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000), - INIT_PARAM(devicename, "Name of device to error on") + INIT_PARAM(devicename, "Name of device to error on"), + INIT_PARAM(pio_addr, "Device Address"), + INIT_PARAM(system, "system object"), + INIT_PARAM(platform, "platform"), + INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000) END_INIT_SIM_OBJECT_PARAMS(BadDevice) CREATE_SIM_OBJECT(BadDevice) { - return new BadDevice(getInstanceName(), addr, mmu, hier, pio_bus, - devicename); + BadDevice::Params *p = new BadDevice::Params; + p->name =getInstanceName(); + p->platform = platform; + p->pio_addr = pio_addr; + p->pio_delay = pio_latency; + p->system = system; + p->device_name = devicename; + return new BadDevice(p); } REGISTER_SIM_OBJECT("BadDevice", BadDevice) diff --git a/dev/baddev.hh b/dev/baddev.hh index 189f28331..4cf0d6ba4 100644 --- a/dev/baddev.hh +++ b/dev/baddev.hh @@ -37,7 +37,6 @@ #include "base/range.hh" #include "dev/io_device.hh" -class MemoryController; /** * BadDevice @@ -45,51 +44,29 @@ class MemoryController; * the user that the kernel they are running has unsupported * options (i.e. frame buffer) */ -class BadDevice : public PioDevice +class BadDevice : public BasicPioDevice { private: - Addr addr; - static const Addr size = 0xf; - std::string devname; public: + struct Params : public BasicPioDevice::Params + { + std::string device_name; + }; + protected: + const Params *params() const { return (const Params *)_params; } + + public: /** * Constructor for the Baddev Class. - * @param name name of the object + * @param p object parameters * @param a base address of the write - * @param mmu the memory controller - * @param hier object to store parameters universal the device hierarchy - * @param bus The bus that this device is attached to - * @param devicename device that is not implemented - */ - BadDevice(const std::string &name, Addr a, MemoryController *mmu, - HierParams *hier, Bus *bus, const std::string &devicename); - - /** - * On a read event we just panic aand hopefully print a - * meaningful error message. - * @param req Contains the address to read from. - * @param data A pointer to write the read data to. - * @return The fault condition of the access. - */ - virtual Fault read(MemReqPtr &req, uint8_t *data); - - /** - * On a write event we just panic aand hopefully print a - * meaningful error message. - * @param req Contains the address to write to. - * @param data The data to write. - * @return The fault condition of the access. */ - virtual Fault write(MemReqPtr &req, const uint8_t *data); + BadDevice(Params *p); - /** - * Return how long this access will take. - * @param req the memory request to calcuate - * @return Tick when the request is done - */ - Tick cacheAccess(MemReqPtr &req); + virtual Tick read(Packet &pkt); + virtual Tick write(Packet &pkt); }; #endif // __DEV_BADDEV_HH__ diff --git a/dev/etherbus.cc b/dev/etherbus.cc index c6b131e8e..906e324d3 100644 --- a/dev/etherbus.cc +++ b/dev/etherbus.cc @@ -81,7 +81,7 @@ EtherBus::reg(EtherInt *dev) { devlist.push_back(dev); } bool -EtherBus::send(EtherInt *sndr, PacketPtr &pkt) +EtherBus::send(EtherInt *sndr, EthPacketPtr &pkt) { if (busy()) { DPRINTF(Ethernet, "ethernet packet not sent, bus busy\n", curTick); diff --git a/dev/etherbus.hh b/dev/etherbus.hh index ca859d85f..4a364abd8 100644 --- a/dev/etherbus.hh +++ b/dev/etherbus.hh @@ -61,7 +61,7 @@ class EtherBus : public SimObject }; DoneEvent event; - PacketPtr packet; + EthPacketPtr packet; EtherInt *sender; EtherDump *dump; @@ -73,7 +73,7 @@ class EtherBus : public SimObject void txDone(); void reg(EtherInt *dev); bool busy() const { return (bool)packet; } - bool send(EtherInt *sender, PacketPtr &packet); + bool send(EtherInt *sender, EthPacketPtr &packet); }; #endif // __ETHERBUS_H__ diff --git a/dev/etherdump.cc b/dev/etherdump.cc index d8a51fc5b..cb5f0b70e 100644 --- a/dev/etherdump.cc +++ b/dev/etherdump.cc @@ -102,7 +102,7 @@ EtherDump::init() } void -EtherDump::dumpPacket(PacketPtr &packet) +EtherDump::dumpPacket(EthPacketPtr &packet) { pcap_pkthdr pkthdr; pkthdr.seconds = curtime + (curTick / Clock::Int::s); diff --git a/dev/etherdump.hh b/dev/etherdump.hh index 149192cd7..8bba073fe 100644 --- a/dev/etherdump.hh +++ b/dev/etherdump.hh @@ -45,7 +45,7 @@ class EtherDump : public SimObject private: std::ofstream stream; const int maxlen; - void dumpPacket(PacketPtr &packet); + void dumpPacket(EthPacketPtr &packet); void init(); Tick curtime; @@ -53,7 +53,7 @@ class EtherDump : public SimObject public: EtherDump(const std::string &name, const std::string &file, int max); - inline void dump(PacketPtr &pkt) { dumpPacket(pkt); } + inline void dump(EthPacketPtr &pkt) { dumpPacket(pkt); } }; #endif // __ETHERDUMP_H__ diff --git a/dev/etherint.hh b/dev/etherint.hh index e397846ae..1f641fadb 100644 --- a/dev/etherint.hh +++ b/dev/etherint.hh @@ -58,9 +58,9 @@ class EtherInt : public SimObject void recvDone() { peer->sendDone(); } virtual void sendDone() = 0; - bool sendPacket(PacketPtr packet) + bool sendPacket(EthPacketPtr packet) { return peer ? peer->recvPacket(packet) : true; } - virtual bool recvPacket(PacketPtr packet) = 0; + virtual bool recvPacket(EthPacketPtr packet) = 0; }; #endif // __DEV_ETHERINT_HH__ diff --git a/dev/etherlink.cc b/dev/etherlink.cc index f68332926..5b6531c2e 100644 --- a/dev/etherlink.cc +++ b/dev/etherlink.cc @@ -102,7 +102,7 @@ EtherLink::unserialize(Checkpoint *cp, const string §ion) } void -EtherLink::Link::txComplete(PacketPtr packet) +EtherLink::Link::txComplete(EthPacketPtr packet) { DPRINTF(Ethernet, "packet received: len=%d\n", packet->length); DDUMP(EthernetData, packet->data, packet->length); @@ -113,12 +113,12 @@ class LinkDelayEvent : public Event { protected: EtherLink::Link *link; - PacketPtr packet; + EthPacketPtr packet; public: // non-scheduling version for createForUnserialize() LinkDelayEvent(); - LinkDelayEvent(EtherLink::Link *link, PacketPtr pkt, Tick when); + LinkDelayEvent(EtherLink::Link *link, EthPacketPtr pkt, Tick when); void process(); @@ -148,7 +148,7 @@ EtherLink::Link::txDone() } bool -EtherLink::Link::transmit(PacketPtr pkt) +EtherLink::Link::transmit(EthPacketPtr pkt) { if (busy()) { DPRINTF(Ethernet, "packet not sent, link busy\n"); @@ -195,7 +195,7 @@ EtherLink::Link::unserialize(const string &base, Checkpoint *cp, bool packet_exists; paramIn(cp, section, base + ".packet_exists", packet_exists); if (packet_exists) { - packet = new PacketData(16384); + packet = new EthPacketData(16384); packet->unserialize(base + ".packet", cp, section); } @@ -215,7 +215,7 @@ LinkDelayEvent::LinkDelayEvent() setFlags(AutoDelete); } -LinkDelayEvent::LinkDelayEvent(EtherLink::Link *l, PacketPtr p, Tick when) +LinkDelayEvent::LinkDelayEvent(EtherLink::Link *l, EthPacketPtr p, Tick when) : Event(&mainEventQueue), link(l), packet(p) { setFlags(AutoSerialize); @@ -256,7 +256,7 @@ LinkDelayEvent::unserialize(Checkpoint *cp, const string §ion) link = parent->link[number]; - packet = new PacketData(16384); + packet = new EthPacketData(16384); packet->unserialize("packet", cp, section); } diff --git a/dev/etherlink.hh b/dev/etherlink.hh index 305007d9e..570444e1b 100644 --- a/dev/etherlink.hh +++ b/dev/etherlink.hh @@ -73,14 +73,14 @@ class EtherLink : public SimObject /* * Transfer is complete */ - PacketPtr packet; + EthPacketPtr packet; void txDone(); typedef EventWrapper<Link, &Link::txDone> DoneEvent; friend void DoneEvent::process(); DoneEvent doneEvent; friend class LinkDelayEvent; - void txComplete(PacketPtr packet); + void txComplete(EthPacketPtr packet); public: Link(const std::string &name, EtherLink *p, int num, @@ -90,7 +90,7 @@ class EtherLink : public SimObject const std::string name() const { return objName; } bool busy() const { return (bool)packet; } - bool transmit(PacketPtr packet); + bool transmit(EthPacketPtr packet); void setTxInt(Interface *i) { assert(!txint); txint = i; } void setRxInt(Interface *i) { assert(!rxint); rxint = i; } @@ -110,7 +110,7 @@ class EtherLink : public SimObject public: Interface(const std::string &name, Link *txlink, Link *rxlink); - bool recvPacket(PacketPtr packet) { return txlink->transmit(packet); } + bool recvPacket(EthPacketPtr packet) { return txlink->transmit(packet); } void sendDone() { peer->sendDone(); } }; diff --git a/dev/etherpkt.cc b/dev/etherpkt.cc index 44dbd7c18..85e18e981 100644 --- a/dev/etherpkt.cc +++ b/dev/etherpkt.cc @@ -35,7 +35,7 @@ using namespace std; void -PacketData::serialize(const string &base, ostream &os) +EthPacketData::serialize(const string &base, ostream &os) { paramOut(os, base + ".length", length); paramOut(os, base + ".slack", slack); @@ -43,7 +43,7 @@ PacketData::serialize(const string &base, ostream &os) } void -PacketData::unserialize(const string &base, Checkpoint *cp, +EthPacketData::unserialize(const string &base, Checkpoint *cp, const string §ion) { paramIn(cp, section, base + ".length", length); diff --git a/dev/etherpkt.hh b/dev/etherpkt.hh index cb9022d72..01741b3d5 100644 --- a/dev/etherpkt.hh +++ b/dev/etherpkt.hh @@ -44,7 +44,7 @@ * Reference counted class containing ethernet packet data */ class Checkpoint; -class PacketData : public RefCounted +class EthPacketData : public RefCounted { public: /* @@ -66,12 +66,12 @@ class PacketData : public RefCounted int slack; public: - PacketData() : data(NULL), length(0), slack(0) { } - explicit PacketData(size_t size) + EthPacketData() : data(NULL), length(0), slack(0) { } + explicit EthPacketData(size_t size) : data(new uint8_t[size]), length(0), slack(0) { } - PacketData(std::auto_ptr<uint8_t> d, int l, int s = 0) + EthPacketData(std::auto_ptr<uint8_t> d, int l, int s = 0) : data(d.release()), length(l), slack(s) { } - ~PacketData() { if (data) delete [] data; } + ~EthPacketData() { if (data) delete [] data; } public: void serialize(const std::string &base, std::ostream &os); @@ -79,6 +79,6 @@ class PacketData : public RefCounted const std::string §ion); }; -typedef RefCountingPtr<PacketData> PacketPtr; +typedef RefCountingPtr<EthPacketData> EthPacketPtr; #endif // __ETHERPKT_HH__ diff --git a/dev/ethertap.cc b/dev/ethertap.cc index 7589991ef..b5abb1d62 100644 --- a/dev/ethertap.cc +++ b/dev/ethertap.cc @@ -169,7 +169,7 @@ EtherTap::detach() } bool -EtherTap::recvPacket(PacketPtr packet) +EtherTap::recvPacket(EthPacketPtr packet) { if (dump) dump->dump(packet); @@ -218,8 +218,8 @@ EtherTap::process(int revent) } while (data_len != 0 && buffer_offset >= data_len + sizeof(u_int32_t)) { - PacketPtr packet; - packet = new PacketData(data_len); + EthPacketPtr packet; + packet = new EthPacketData(data_len); packet->length = data_len; memcpy(packet->data, data, data_len); @@ -250,7 +250,7 @@ EtherTap::retransmit() if (packetBuffer.empty()) return; - PacketPtr packet = packetBuffer.front(); + EthPacketPtr packet = packetBuffer.front(); if (sendPacket(packet)) { if (dump) dump->dump(packet); diff --git a/dev/ethertap.hh b/dev/ethertap.hh index 069ba734f..40ce6af0b 100644 --- a/dev/ethertap.hh +++ b/dev/ethertap.hh @@ -70,10 +70,10 @@ class EtherTap : public EtherInt protected: std::string device; - std::queue<PacketPtr> packetBuffer; + std::queue<EthPacketPtr> packetBuffer; void process(int revent); - void enqueue(PacketData *packet); + void enqueue(EthPacketData *packet); void retransmit(); /* @@ -97,7 +97,7 @@ class EtherTap : public EtherInt EtherTap(const std::string &name, EtherDump *dump, int port, int bufsz); virtual ~EtherTap(); - virtual bool recvPacket(PacketPtr packet); + virtual bool recvPacket(EthPacketPtr packet); virtual void sendDone(); virtual void serialize(std::ostream &os); diff --git a/dev/ide_ctrl.cc b/dev/ide_ctrl.cc index 05c756f04..abdbe5d0a 100644 --- a/dev/ide_ctrl.cc +++ b/dev/ide_ctrl.cc @@ -38,17 +38,12 @@ #include "dev/pciconfigall.hh" #include "dev/pcireg.h" #include "dev/platform.hh" -#include "mem/bus/bus.hh" -#include "mem/bus/dma_interface.hh" -#include "mem/bus/pio_interface.hh" -#include "mem/bus/pio_interface_impl.hh" -#include "mem/functional/memory_control.hh" -#include "mem/functional/physical.hh" +#include "mem/packet.hh" #include "sim/builder.hh" #include "sim/sim_object.hh" +#include "sim/byteswap.hh" using namespace std; -using namespace TheISA; //// // Initialization and destruction @@ -91,22 +86,6 @@ IdeController::IdeController(Params *p) bm_enabled = false; memset(cmd_in_progress, 0, sizeof(cmd_in_progress)); - pioInterface = NULL; - dmaInterface = NULL; - // create the PIO and DMA interfaces - if (params()->pio_bus) { - pioInterface = newPioInterface(name() + ".pio", params()->hier, - params()->pio_bus, this, - &IdeController::cacheAccess); - pioLatency = params()->pio_latency * params()->pio_bus->clockRate; - } - - if (params()->dma_bus) { - dmaInterface = new DMAInterface<Bus>(name() + ".dma", - params()->dma_bus, - params()->dma_bus, 1, true); - } - // setup the disks attached to controller memset(disks, 0, sizeof(disks)); dev[0] = 0; @@ -117,7 +96,7 @@ IdeController::IdeController(Params *p) for (int i = 0; i < params()->disks.size(); i++) { disks[i] = params()->disks[i]; - disks[i]->setController(this, dmaInterface); + disks[i]->setController(this); } } @@ -239,121 +218,158 @@ IdeController::setDmaComplete(IdeDisk *disk) } } -//// -// Bus timing and bus access functions -//// - -Tick -IdeController::cacheAccess(MemReqPtr &req) -{ - // @todo Add more accurate timing to cache access - return curTick + pioLatency; -} //// // Read and write handling //// void -IdeController::readConfig(int offset, int size, uint8_t *data) +IdeController::readConfig(int offset, uint8_t *data) { - int config_offset; - if (offset < PCI_DEVICE_SPECIFIC) { - PciDev::readConfig(offset, size, data); + PciDev::readConfig(offset, data); } else if (offset >= IDE_CTRL_CONF_START && - (offset + size) <= IDE_CTRL_CONF_END) { + (offset + 1) <= IDE_CTRL_CONF_END) { - config_offset = offset - IDE_CTRL_CONF_START; - - switch (size) { - case sizeof(uint8_t): - *data = config_regs.data[config_offset]; + switch (offset) { + case IDE_CTRL_CONF_DEV_TIMING: + *data = config_regs.sidetim; break; - case sizeof(uint16_t): - *(uint16_t*)data = *(uint16_t*)&config_regs.data[config_offset]; + case IDE_CTRL_CONF_UDMA_CNTRL: + *data = config_regs.udmactl; break; - case sizeof(uint32_t): - *(uint32_t*)data = *(uint32_t*)&config_regs.data[config_offset]; + case IDE_CTRL_CONF_PRIM_TIMING+1: + *data = htole(config_regs.idetim0) >> 8; + break; + case IDE_CTRL_CONF_SEC_TIMING+1: + *data = htole(config_regs.idetim1) >> 8; + break; + case IDE_CTRL_CONF_IDE_CONFIG: + *data = htole(config_regs.ideconfig) & 0xFF; + break; + case IDE_CTRL_CONF_IDE_CONFIG+1: + *data = htole(config_regs.ideconfig) >> 8; break; default: - panic("Invalid PCI configuration read size!\n"); + panic("Invalid PCI configuration read for size 1 at offset: %#x!\n", + offset); } - - } else { panic("Read of unimplemented PCI config. register: %x\n", offset); } - switch (size) { - case sizeof(uint8_t): - DPRINTF(IdeCtrl, "PCI read offset: %#x size: %d data: %#x\n", - offset, size, (uint32_t)*data); + DPRINTF(IdeCtrl, "PCI read offset: %#x size: 1 data: %#x\n", + offset, (uint32_t)*data); +} + +void +IdeController::readConfig(int offset, uint16_t *data) +{ + if (offset < PCI_DEVICE_SPECIFIC) { + PciDev::readConfig(offset, data); + } else if (offset >= IDE_CTRL_CONF_START && + (offset + 2) <= IDE_CTRL_CONF_END) { + + switch (offset) { + case IDE_CTRL_CONF_PRIM_TIMING: + *data = config_regs.idetim0; break; - case sizeof(uint16_t): - DPRINTF(IdeCtrl, "PCI read offset: %#x size: %d data: %#x\n", - offset, size, *(uint16_t*)data); + case IDE_CTRL_CONF_SEC_TIMING: + *data = config_regs.idetim1; break; - case sizeof(uint32_t): - DPRINTF(IdeCtrl, "PCI read offset: %#x size: %d data: %#x\n", - offset, size, *(uint32_t*)data); + case IDE_CTRL_CONF_UDMA_TIMING: + *data = config_regs.udmatim; + break; + case IDE_CTRL_CONF_IDE_CONFIG: + *data = config_regs.ideconfig; break; default: - panic("Invalid PCI configuration read size!\n"); + panic("Invalid PCI configuration read for size 2 offset: %#x!\n", + offset); } + } else { + panic("Read of unimplemented PCI config. register: %x\n", offset); + } + DPRINTF(IdeCtrl, "PCI read offset: %#x size: 2 data: %#x\n", offset, *data); } void -IdeController::writeConfig(int offset, int size, const uint8_t *data) +IdeController::readConfig(int offset, uint32_t *data) { - int config_offset; - if (offset < PCI_DEVICE_SPECIFIC) { - PciDev::writeConfig(offset, size, data); + PciDev::readConfig(offset, data); + } else { + panic("Read of unimplemented PCI config. register: %x\n", offset); + } + DPRINTF(IdeCtrl, "PCI read offset: %#x size: 4 data: %#x\n", offset, *data); +} +void +IdeController::writeConfig(int offset, const uint8_t data) +{ + if (offset < PCI_DEVICE_SPECIFIC) { + PciDev::writeConfig(offset, data); } else if (offset >= IDE_CTRL_CONF_START && - (offset + size) <= IDE_CTRL_CONF_END) { + (offset + 1) <= IDE_CTRL_CONF_END) { - config_offset = offset - IDE_CTRL_CONF_START; - - switch(size) { - case sizeof(uint8_t): - config_regs.data[config_offset] = *data; + switch (offset) { + case IDE_CTRL_CONF_DEV_TIMING: + config_regs.sidetim = data; break; - case sizeof(uint16_t): - *(uint16_t*)&config_regs.data[config_offset] = *(uint16_t*)data; + case IDE_CTRL_CONF_UDMA_CNTRL: + config_regs.udmactl = data; break; - case sizeof(uint32_t): - *(uint32_t*)&config_regs.data[config_offset] = *(uint32_t*)data; + case IDE_CTRL_CONF_IDE_CONFIG: + config_regs.ideconfig = (config_regs.ideconfig & 0xFF00) | (data); + break; + case IDE_CTRL_CONF_IDE_CONFIG+1: + config_regs.ideconfig = (config_regs.ideconfig & 0x00FF) | data << 8; break; default: - panic("Invalid PCI configuration write size!\n"); + panic("Invalid PCI configuration write for size 1 offset: %#x!\n", + offset); } + } else { - panic("Write of unimplemented PCI config. register: %x\n", offset); + panic("Read of unimplemented PCI config. register: %x\n", offset); } + DPRINTF(IdeCtrl, "PCI write offset: %#x size: 1 data: %#x\n", + offset, (uint32_t)data); +} - switch(size) { - case sizeof(uint8_t): - DPRINTF(IdeCtrl, "PCI write offset: %#x size: %d data: %#x\n", - offset, size, (uint32_t)*data); +void +IdeController::writeConfig(int offset, const uint16_t data) +{ + if (offset < PCI_DEVICE_SPECIFIC) { + PciDev::writeConfig(offset, data); + } else if (offset >= IDE_CTRL_CONF_START && + (offset + 2) <= IDE_CTRL_CONF_END) { + + switch (offset) { + case IDE_CTRL_CONF_PRIM_TIMING: + config_regs.idetim0 = data; break; - case sizeof(uint16_t): - DPRINTF(IdeCtrl, "PCI write offset: %#x size: %d data: %#x\n", - offset, size, *(uint16_t*)data); + case IDE_CTRL_CONF_SEC_TIMING: + config_regs.idetim1 = data; break; - case sizeof(uint32_t): - DPRINTF(IdeCtrl, "PCI write offset: %#x size: %d data: %#x\n", - offset, size, *(uint32_t*)data); + case IDE_CTRL_CONF_UDMA_TIMING: + config_regs.udmatim = data; + break; + case IDE_CTRL_CONF_IDE_CONFIG: + config_regs.ideconfig = data; break; default: - panic("Invalid PCI configuration write size!\n"); + panic("Invalid PCI configuration write for size 2 offset: %#x!\n", + offset); } - // Catch the writes to specific PCI registers that have side affects - // (like updating the PIO ranges) - switch (offset) { - case PCI_COMMAND: + } else { + panic("Write of unimplemented PCI config. register: %x\n", offset); + } + DPRINTF(IdeCtrl, "PCI write offset: %#x size: 2 data: %#x\n", offset, data); + + /* Trap command register writes and enable IO/BM as appropriate. */ + if (offset == PCI_COMMAND) { if (letoh(config.command) & PCI_CMD_IOSE) io_enabled = true; else @@ -363,91 +379,83 @@ IdeController::writeConfig(int offset, int size, const uint8_t *data) bm_enabled = true; else bm_enabled = false; - break; + } + +} + +void +IdeController::writeConfig(int offset, const uint32_t data) +{ + if (offset < PCI_DEVICE_SPECIFIC) { + PciDev::writeConfig(offset, data); + } else { + panic("Read of unimplemented PCI config. register: %x\n", offset); + } + + DPRINTF(IdeCtrl, "PCI write offset: %#x size: 4 data: %#x\n", offset, data); + switch(offset) { case PCI0_BASE_ADDR0: - if (BARAddrs[0] != 0) { + if (BARAddrs[0] != 0) pri_cmd_addr = BARAddrs[0]; - if (pioInterface) - pioInterface->addAddrRange(RangeSize(pri_cmd_addr, - pri_cmd_size)); - - pri_cmd_addr &= EV5::PAddrUncachedMask; - } break; case PCI0_BASE_ADDR1: - if (BARAddrs[1] != 0) { + if (BARAddrs[1] != 0) pri_ctrl_addr = BARAddrs[1]; - if (pioInterface) - pioInterface->addAddrRange(RangeSize(pri_ctrl_addr, - pri_ctrl_size)); - - pri_ctrl_addr &= EV5::PAddrUncachedMask; - } break; case PCI0_BASE_ADDR2: - if (BARAddrs[2] != 0) { + if (BARAddrs[2] != 0) sec_cmd_addr = BARAddrs[2]; - if (pioInterface) - pioInterface->addAddrRange(RangeSize(sec_cmd_addr, - sec_cmd_size)); - - sec_cmd_addr &= EV5::PAddrUncachedMask; - } break; case PCI0_BASE_ADDR3: - if (BARAddrs[3] != 0) { + if (BARAddrs[3] != 0) sec_ctrl_addr = BARAddrs[3]; - if (pioInterface) - pioInterface->addAddrRange(RangeSize(sec_ctrl_addr, - sec_ctrl_size)); - - sec_ctrl_addr &= EV5::PAddrUncachedMask; - } break; case PCI0_BASE_ADDR4: - if (BARAddrs[4] != 0) { + if (BARAddrs[4] != 0) bmi_addr = BARAddrs[4]; - if (pioInterface) - pioInterface->addAddrRange(RangeSize(bmi_addr, bmi_size)); - - bmi_addr &= EV5::PAddrUncachedMask; - } break; } } -Fault -IdeController::read(MemReqPtr &req, uint8_t *data) +Tick +IdeController::read(Packet &pkt) { Addr offset; IdeChannel channel; IdeRegType reg_type; int disk; - parseAddr(req->paddr, offset, channel, reg_type); + pkt.time += pioDelay; + pkt.allocate(); + if (pkt.size != 1 && pkt.size != 2 && pkt.size !=4) + panic("Bad IDE read size: %d\n", pkt.size); + + parseAddr(pkt.addr, offset, channel, reg_type); - if (!io_enabled) - return NoFault; + if (!io_enabled) { + pkt.result = Success; + return pioDelay; + } switch (reg_type) { case BMI_BLOCK: - switch (req->size) { + switch (pkt.size) { case sizeof(uint8_t): - *data = bmi_regs.data[offset]; + pkt.set(bmi_regs.data[offset]); break; case sizeof(uint16_t): - *(uint16_t*)data = *(uint16_t*)&bmi_regs.data[offset]; + pkt.set(*(uint16_t*)&bmi_regs.data[offset]); break; case sizeof(uint32_t): - *(uint32_t*)data = *(uint32_t*)&bmi_regs.data[offset]; + pkt.set(*(uint32_t*)&bmi_regs.data[offset]); break; default: - panic("IDE read of BMI reg invalid size: %#x\n", req->size); + panic("IDE read of BMI reg invalid size: %#x\n", pkt.size); } break; @@ -455,51 +463,54 @@ IdeController::read(MemReqPtr &req, uint8_t *data) case CONTROL_BLOCK: disk = getDisk(channel); - if (disks[disk] == NULL) + if (disks[disk] == NULL) { + pkt.set<uint8_t>(0); break; + } switch (offset) { case DATA_OFFSET: - switch (req->size) { + switch (pkt.size) { case sizeof(uint16_t): - disks[disk]->read(offset, reg_type, data); + disks[disk]->read(offset, reg_type, pkt.getPtr<uint8_t>()); break; case sizeof(uint32_t): - disks[disk]->read(offset, reg_type, data); - disks[disk]->read(offset, reg_type, &data[2]); + disks[disk]->read(offset, reg_type, pkt.getPtr<uint8_t>()); + disks[disk]->read(offset, reg_type, + pkt.getPtr<uint8_t>() + sizeof(uint16_t)); break; default: - panic("IDE read of data reg invalid size: %#x\n", req->size); + panic("IDE read of data reg invalid size: %#x\n", pkt.size); } break; default: - if (req->size == sizeof(uint8_t)) { - disks[disk]->read(offset, reg_type, data); + if (pkt.size == sizeof(uint8_t)) { + disks[disk]->read(offset, reg_type, pkt.getPtr<uint8_t>()); } else - panic("IDE read of command reg of invalid size: %#x\n", req->size); + panic("IDE read of command reg of invalid size: %#x\n", pkt.size); } break; default: panic("IDE controller read of unknown register block type!\n"); } - - if (req->size == 1) + if (pkt.size == 1) DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n", - offset, req->size, (uint32_t)*data); - else if (req->size == 2) + offset, pkt.size, (uint32_t)pkt.get<uint8_t>()); + else if (pkt.size == 2) DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n", - offset, req->size, *(uint16_t*)data); + offset, pkt.size, pkt.get<uint16_t>()); else DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n", - offset, req->size, *(uint32_t*)data); + offset, pkt.size, pkt.get<uint32_t>()); - return NoFault; + pkt.result = Success; + return pioDelay; } -Fault -IdeController::write(MemReqPtr &req, const uint8_t *data) +Tick +IdeController::write(Packet &pkt) { Addr offset; IdeChannel channel; @@ -507,28 +518,35 @@ IdeController::write(MemReqPtr &req, const uint8_t *data) int disk; uint8_t oldVal, newVal; - parseAddr(req->paddr, offset, channel, reg_type); + pkt.time += pioDelay; - if (!io_enabled) - return NoFault; + parseAddr(pkt.addr, offset, channel, reg_type); + + if (!io_enabled) { + pkt.result = Success; + DPRINTF(IdeCtrl, "io not enabled\n"); + return pioDelay; + } switch (reg_type) { case BMI_BLOCK: - if (!bm_enabled) - return NoFault; + if (!bm_enabled) { + pkt.result = Success; + return pioDelay; + } switch (offset) { // Bus master IDE command register case BMIC1: case BMIC0: - if (req->size != sizeof(uint8_t)) - panic("Invalid BMIC write size: %x\n", req->size); + if (pkt.size != sizeof(uint8_t)) + panic("Invalid BMIC write size: %x\n", pkt.size); // select the current disk based on DEV bit disk = getDisk(channel); oldVal = bmi_regs.chan[channel].bmic; - newVal = *data; + newVal = pkt.get<uint8_t>(); // if a DMA transfer is in progress, R/W control cannot change if (oldVal & SSBM) { @@ -577,11 +595,11 @@ IdeController::write(MemReqPtr &req, const uint8_t *data) // Bus master IDE status register case BMIS0: case BMIS1: - if (req->size != sizeof(uint8_t)) - panic("Invalid BMIS write size: %x\n", req->size); + if (pkt.size != sizeof(uint8_t)) + panic("Invalid BMIS write size: %x\n", pkt.size); oldVal = bmi_regs.chan[channel].bmis; - newVal = *data; + newVal = pkt.get<uint8_t>(); // the BMIDEA bit is RO newVal |= (oldVal & BMIDEA); @@ -604,30 +622,28 @@ IdeController::write(MemReqPtr &req, const uint8_t *data) case BMIDTP0: case BMIDTP1: { - if (req->size != sizeof(uint32_t)) - panic("Invalid BMIDTP write size: %x\n", req->size); + if (pkt.size != sizeof(uint32_t)) + panic("Invalid BMIDTP write size: %x\n", pkt.size); - uint32_t host_data = letoh(*(uint32_t*)data); - host_data &= ~0x3; - bmi_regs.chan[channel].bmidtp = htole(host_data); + bmi_regs.chan[channel].bmidtp = htole(pkt.get<uint32_t>() & ~0x3); } break; default: - if (req->size != sizeof(uint8_t) && - req->size != sizeof(uint16_t) && - req->size != sizeof(uint32_t)) + if (pkt.size != sizeof(uint8_t) && + pkt.size != sizeof(uint16_t) && + pkt.size != sizeof(uint32_t)) panic("IDE controller write of invalid write size: %x\n", - req->size); + pkt.size); // do a default copy of data into the registers - memcpy(&bmi_regs.data[offset], data, req->size); + memcpy(&bmi_regs.data[offset], pkt.getPtr<uint8_t>(), pkt.size); } break; case COMMAND_BLOCK: if (offset == IDE_SELECT_OFFSET) { uint8_t *devBit = &dev[channel]; - *devBit = (letoh(*data) & IDE_SELECT_DEV_BIT) ? 1 : 0; + *devBit = (letoh(pkt.get<uint8_t>()) & IDE_SELECT_DEV_BIT) ? 1 : 0; } // fall-through ok! case CONTROL_BLOCK: @@ -638,40 +654,44 @@ IdeController::write(MemReqPtr &req, const uint8_t *data) switch (offset) { case DATA_OFFSET: - switch (req->size) { + switch (pkt.size) { case sizeof(uint16_t): - disks[disk]->write(offset, reg_type, data); + disks[disk]->write(offset, reg_type, pkt.getPtr<uint8_t>()); break; case sizeof(uint32_t): - disks[disk]->write(offset, reg_type, data); - disks[disk]->write(offset, reg_type, &data[2]); + disks[disk]->write(offset, reg_type, pkt.getPtr<uint8_t>()); + disks[disk]->write(offset, reg_type, pkt.getPtr<uint8_t>() + + sizeof(uint16_t)); break; default: - panic("IDE write of data reg invalid size: %#x\n", req->size); + panic("IDE write of data reg invalid size: %#x\n", pkt.size); } break; default: - if (req->size == sizeof(uint8_t)) { - disks[disk]->write(offset, reg_type, data); + if (pkt.size == sizeof(uint8_t)) { + disks[disk]->write(offset, reg_type, pkt.getPtr<uint8_t>()); } else - panic("IDE write of command reg of invalid size: %#x\n", req->size); + panic("IDE write of command reg of invalid size: %#x\n", pkt.size); } break; default: panic("IDE controller write of unknown register block type!\n"); } - if (req->size == 1) + + if (pkt.size == 1) DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n", - offset, req->size, (uint32_t)*data); - else if (req->size == 2) + offset, pkt.size, (uint32_t)pkt.get<uint8_t>()); + else if (pkt.size == 2) DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n", - offset, req->size, *(uint16_t*)data); + offset, pkt.size, pkt.get<uint16_t>()); else DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n", - offset, req->size, *(uint32_t*)data); + offset, pkt.size, pkt.get<uint32_t>()); - return NoFault; + + pkt.result = Success; + return pioDelay; } //// @@ -740,51 +760,36 @@ IdeController::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(bm_enabled); UNSERIALIZE_ARRAY(cmd_in_progress, sizeof(cmd_in_progress) / sizeof(cmd_in_progress[0])); - - if (pioInterface) { - pioInterface->addAddrRange(RangeSize(pri_cmd_addr, pri_cmd_size)); - pioInterface->addAddrRange(RangeSize(pri_ctrl_addr, pri_ctrl_size)); - pioInterface->addAddrRange(RangeSize(sec_cmd_addr, sec_cmd_size)); - pioInterface->addAddrRange(RangeSize(sec_ctrl_addr, sec_ctrl_size)); - pioInterface->addAddrRange(RangeSize(bmi_addr, bmi_size)); - } + pioPort->sendStatusChange(Port::RangeChange); } #ifndef DOXYGEN_SHOULD_SKIP_THIS BEGIN_DECLARE_SIM_OBJECT_PARAMS(IdeController) - Param<Addr> addr; - SimObjectVectorParam<IdeDisk *> disks; - SimObjectParam<MemoryController *> mmu; + SimObjectParam<System *> system; + SimObjectParam<Platform *> platform; SimObjectParam<PciConfigAll *> configspace; SimObjectParam<PciConfigData *> configdata; - SimObjectParam<Platform *> platform; Param<uint32_t> pci_bus; Param<uint32_t> pci_dev; Param<uint32_t> pci_func; - SimObjectParam<Bus *> pio_bus; - SimObjectParam<Bus *> dma_bus; Param<Tick> pio_latency; - SimObjectParam<HierParams *> hier; + SimObjectVectorParam<IdeDisk *> disks; END_DECLARE_SIM_OBJECT_PARAMS(IdeController) BEGIN_INIT_SIM_OBJECT_PARAMS(IdeController) - INIT_PARAM(addr, "Device Address"), - INIT_PARAM(disks, "IDE disks attached to this controller"), - INIT_PARAM(mmu, "Memory controller"), + INIT_PARAM(system, "System pointer"), + INIT_PARAM(platform, "Platform pointer"), INIT_PARAM(configspace, "PCI Configspace"), INIT_PARAM(configdata, "PCI Config data"), - INIT_PARAM(platform, "Platform pointer"), INIT_PARAM(pci_bus, "PCI bus ID"), INIT_PARAM(pci_dev, "PCI device number"), INIT_PARAM(pci_func, "PCI function code"), - INIT_PARAM(pio_bus, ""), - INIT_PARAM(dma_bus, ""), INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1), - INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) + INIT_PARAM(disks, "IDE disks attached to this controller") END_INIT_SIM_OBJECT_PARAMS(IdeController) @@ -792,19 +797,15 @@ CREATE_SIM_OBJECT(IdeController) { IdeController::Params *params = new IdeController::Params; params->name = getInstanceName(); - params->mmu = mmu; + params->platform = platform; + params->system = system; params->configSpace = configspace; params->configData = configdata; - params->plat = platform; params->busNum = pci_bus; params->deviceNum = pci_dev; params->functionNum = pci_func; - + params->pio_delay = pio_latency; params->disks = disks; - params->pio_bus = pio_bus; - params->dma_bus = dma_bus; - params->pio_latency = pio_latency; - params->hier = hier; return new IdeController(params); } diff --git a/dev/ide_ctrl.hh b/dev/ide_ctrl.hh index 0fbaf9207..a074f4f97 100644 --- a/dev/ide_ctrl.hh +++ b/dev/ide_ctrl.hh @@ -70,6 +70,13 @@ #define IDE_CTRL_CONF_START 0x40 #define IDE_CTRL_CONF_END ((IDE_CTRL_CONF_START) + sizeof(config_regs)) +#define IDE_CTRL_CONF_PRIM_TIMING 0x40 +#define IDE_CTRL_CONF_SEC_TIMING 0x42 +#define IDE_CTRL_CONF_DEV_TIMING 0x44 +#define IDE_CTRL_CONF_UDMA_CNTRL 0x48 +#define IDE_CTRL_CONF_UDMA_TIMING 0x4A +#define IDE_CTRL_CONF_IDE_CONFIG 0x54 + enum IdeRegType { COMMAND_BLOCK, @@ -77,13 +84,9 @@ enum IdeRegType { BMI_BLOCK }; -class BaseInterface; -class Bus; -class HierParams; class IdeDisk; class IntrControl; class PciConfigAll; -class PhysicalMemory; class Platform; /** @@ -191,10 +194,6 @@ class IdeController : public PciDev { /** Array of disk objects */ std::vector<IdeDisk *> disks; - Bus *pio_bus; - Bus *dma_bus; - Tick pio_latency; - HierParams *hier; }; const Params *params() const { return (const Params *)_params; } @@ -202,26 +201,28 @@ class IdeController : public PciDev IdeController(Params *p); ~IdeController(); - virtual void writeConfig(int offset, int size, const uint8_t *data); - virtual void readConfig(int offset, int size, uint8_t *data); + virtual void writeConfig(int offset, const uint8_t data); + virtual void writeConfig(int offset, const uint16_t data); + virtual void writeConfig(int offset, const uint32_t data); + virtual void readConfig(int offset, uint8_t *data); + virtual void readConfig(int offset, uint16_t *data); + virtual void readConfig(int offset, uint32_t *data); void setDmaComplete(IdeDisk *disk); /** * Read a done field for a given target. - * @param req Contains the address of the field to read. - * @param data Return the field read. - * @return The fault condition of the access. + * @param pkt Packet describing what is to be read + * @return The amount of time to complete this request */ - virtual Fault read(MemReqPtr &req, uint8_t *data); + virtual Tick read(Packet &pkt); /** - * Write to the mmapped I/O control registers. - * @param req Contains the address to write to. - * @param data The data to write. - * @return The fault condition of the access. + * Write a done field for a given target. + * @param pkt Packet describing what is to be written + * @return The amount of time to complete this request */ - virtual Fault write(MemReqPtr &req, const uint8_t *data); + virtual Tick write(Packet &pkt); /** * Serialize this object to the given output stream. @@ -236,11 +237,5 @@ class IdeController : public PciDev */ virtual void unserialize(Checkpoint *cp, const std::string §ion); - /** - * Return how long this access will take. - * @param req the memory request to calcuate - * @return Tick when the request is done - */ - Tick cacheAccess(MemReqPtr &req); }; #endif // __IDE_CTRL_HH_ diff --git a/dev/ide_disk.cc b/dev/ide_disk.cc index c13556ed6..6f4234a1d 100644 --- a/dev/ide_disk.cc +++ b/dev/ide_disk.cc @@ -35,6 +35,7 @@ #include <deque> #include <string> +#include "base/chunk_generator.hh" #include "base/cprintf.hh" // csprintf #include "base/trace.hh" #include "dev/disk_image.hh" @@ -42,11 +43,6 @@ #include "dev/ide_ctrl.hh" #include "dev/tsunami.hh" #include "dev/tsunami_pchip.hh" -#include "mem/functional/physical.hh" -#include "mem/bus/bus.hh" -#include "mem/bus/dma_interface.hh" -#include "mem/bus/pio_interface.hh" -#include "mem/bus/pio_interface_impl.hh" #include "sim/builder.hh" #include "sim/sim_object.hh" #include "sim/root.hh" @@ -55,11 +51,11 @@ using namespace std; using namespace TheISA; -IdeDisk::IdeDisk(const string &name, DiskImage *img, PhysicalMemory *phys, +IdeDisk::IdeDisk(const string &name, DiskImage *img, int id, Tick delay) - : SimObject(name), ctrl(NULL), image(img), physmem(phys), diskDelay(delay), - dmaTransferEvent(this), dmaReadWaitEvent(this), - dmaWriteWaitEvent(this), dmaPrdReadEvent(this), + : SimObject(name), ctrl(NULL), image(img), diskDelay(delay), + dmaTransferEvent(this), dmaReadCG(NULL), dmaReadWaitEvent(this), + dmaWriteCG(NULL), dmaWriteWaitEvent(this), dmaPrdReadEvent(this), dmaReadEvent(this), dmaWriteEvent(this) { // Reset the device state @@ -139,7 +135,6 @@ IdeDisk::reset(int id) memset(&cmdReg, 0, sizeof(CommandReg_t)); memset(&curPrd.entry, 0, sizeof(PrdEntry_t)); - dmaInterfaceBytes = 0; curPrdAddr = 0; curSector = 0; cmdBytes = 0; @@ -188,29 +183,6 @@ IdeDisk::pciToDma(Addr pciAddr) panic("Access to unset controller!\n"); } -uint32_t -IdeDisk::bytesInDmaPage(Addr curAddr, uint32_t bytesLeft) -{ - uint32_t bytesInPage = 0; - - // First calculate how many bytes could be in the page - if (bytesLeft > TheISA::PageBytes) - bytesInPage = TheISA::PageBytes; - else - bytesInPage = bytesLeft; - - // Next, see if we have crossed a page boundary, and adjust - Addr upperBound = curAddr + bytesInPage; - Addr pageBound = TheISA::TruncPage(curAddr) + TheISA::PageBytes; - - assert(upperBound >= curAddr && "DMA read wraps around address space!\n"); - - if (upperBound >= pageBound) - bytesInPage = pageBound - curAddr; - - return bytesInPage; -} - //// // Device registers read/write //// @@ -263,6 +235,8 @@ IdeDisk::read(const Addr &offset, IdeRegType reg_type, uint8_t *data) default: panic("Unknown register block!\n"); } + DPRINTF(IdeDisk, "Read to disk at offset: %#x data %#x\n", offset, + (uint32_t)*data); if (action != ACT_NONE) updateState(action); @@ -324,6 +298,8 @@ IdeDisk::write(const Addr &offset, IdeRegType reg_type, const uint8_t *data) panic("Unknown register block!\n"); } + DPRINTF(IdeDisk, "Write to disk at offset: %#x data %#x\n", offset, + (uint32_t)*data); if (action != ACT_NONE) updateState(action); } @@ -339,29 +315,17 @@ IdeDisk::doDmaTransfer() panic("Inconsistent DMA transfer state: dmaState = %d devState = %d\n", dmaState, devState); - // first read the current PRD - if (dmaInterface) { - if (dmaInterface->busy()) { - // reschedule after waiting period - dmaTransferEvent.schedule(curTick + DMA_BACKOFF_PERIOD); - return; - } - - dmaInterface->doDMA(Read, curPrdAddr, sizeof(PrdEntry_t), curTick, - &dmaPrdReadEvent); - } else { - dmaPrdReadDone(); - } + if (ctrl->dmaPending()) { + dmaTransferEvent.schedule(curTick + DMA_BACKOFF_PERIOD); + return; + } else + ctrl->dmaRead(curPrdAddr, sizeof(PrdEntry_t), &dmaPrdReadEvent, + (uint8_t*)&curPrd.entry); } void IdeDisk::dmaPrdReadDone() { - // actually copy the PRD from physical memory - memcpy((void *)&curPrd.entry, - physmem->dma_addr(curPrdAddr, sizeof(PrdEntry_t)), - sizeof(PrdEntry_t)); - DPRINTF(IdeDisk, "PRD: baseAddr:%#x (%#x) byteCount:%d (%d) eot:%#x sector:%d\n", curPrd.getBaseAddr(), pciToDma(curPrd.getBaseAddr()), @@ -372,73 +336,49 @@ IdeDisk::dmaPrdReadDone() curPrdAddr = curPrdAddr + sizeof(PrdEntry_t); if (dmaRead) - doDmaRead(); + doDmaDataRead(); else - doDmaWrite(); + doDmaDataWrite(); } void -IdeDisk::regStats() -{ - using namespace Stats; - dmaReadFullPages - .name(name() + ".dma_read_full_pages") - .desc("Number of full page size DMA reads (not PRD).") - ; - dmaReadBytes - .name(name() + ".dma_read_bytes") - .desc("Number of bytes transfered via DMA reads (not PRD).") - ; - dmaReadTxs - .name(name() + ".dma_read_txs") - .desc("Number of DMA read transactions (not PRD).") - ; - - dmaWriteFullPages - .name(name() + ".dma_write_full_pages") - .desc("Number of full page size DMA writes.") - ; - dmaWriteBytes - .name(name() + ".dma_write_bytes") - .desc("Number of bytes transfered via DMA writes.") - ; - dmaWriteTxs - .name(name() + ".dma_write_txs") - .desc("Number of DMA write transactions.") - ; -} - -void -IdeDisk::doDmaRead() +IdeDisk::doDmaDataRead() { /** @todo we need to figure out what the delay actually will be */ Tick totalDiskDelay = diskDelay + (curPrd.getByteCount() / SectorSize); DPRINTF(IdeDisk, "doDmaRead, diskDelay: %d totalDiskDelay: %d\n", diskDelay, totalDiskDelay); - if (dmaInterface) { - if (dmaInterface->busy()) { - // reschedule after waiting period - dmaReadWaitEvent.schedule(curTick + DMA_BACKOFF_PERIOD); - return; - } - Addr dmaAddr = pciToDma(curPrd.getBaseAddr()); + dmaReadWaitEvent.schedule(curTick + totalDiskDelay); +} - uint32_t bytesInPage = bytesInDmaPage(curPrd.getBaseAddr(), - (uint32_t)curPrd.getByteCount()); - dmaInterfaceBytes = bytesInPage; +void +IdeDisk::doDmaRead() +{ - if (bytesInPage == TheISA::VMPageSize) - dmaReadFullPages++; - dmaReadBytes += bytesInPage; - dmaReadTxs++; - dmaInterface->doDMA(Read, dmaAddr, bytesInPage, - curTick + totalDiskDelay, &dmaReadEvent); + if (!dmaReadCG) { + // clear out the data buffer + memset(dataBuffer, 0, MAX_DMA_SIZE); + dmaReadCG = new ChunkGenerator(curPrd.getBaseAddr(), + curPrd.getByteCount(), TheISA::PageBytes); + + } + if (ctrl->dmaPending()) { + panic("shouldn't be reentant??"); + dmaReadWaitEvent.schedule(curTick + DMA_BACKOFF_PERIOD); + return; + } else if (!dmaReadCG->done()) { + assert(dmaReadCG->complete() < MAX_DMA_SIZE); + ctrl->dmaRead(pciToDma(dmaReadCG->addr()), dmaReadCG->size(), + &dmaReadWaitEvent, dataBuffer + dmaReadCG->complete()); + dmaReadCG->next(); } else { - // schedule dmaReadEvent with sectorDelay (dmaReadDone) - dmaReadEvent.schedule(curTick + totalDiskDelay); + assert(dmaReadCG->done()); + delete dmaReadCG; + dmaReadCG = NULL; + dmaReadDone(); } } @@ -446,68 +386,14 @@ void IdeDisk::dmaReadDone() { - Addr curAddr = 0, dmaAddr = 0; - uint32_t bytesWritten = 0, bytesInPage = 0, bytesLeft = 0; - - // continue to use the DMA interface until all pages are read - if (dmaInterface && (dmaInterfaceBytes < curPrd.getByteCount())) { - // see if the interface is busy - if (dmaInterface->busy()) { - // reschedule after waiting period - dmaReadEvent.schedule(curTick + DMA_BACKOFF_PERIOD); - return; - } - - uint32_t bytesLeft = curPrd.getByteCount() - dmaInterfaceBytes; - curAddr = curPrd.getBaseAddr() + dmaInterfaceBytes; - dmaAddr = pciToDma(curAddr); - - bytesInPage = bytesInDmaPage(curAddr, bytesLeft); - dmaInterfaceBytes += bytesInPage; - - if (bytesInPage == TheISA::VMPageSize) - dmaReadFullPages++; - dmaReadBytes += bytesInPage; - dmaReadTxs++; - - dmaInterface->doDMA(Read, dmaAddr, bytesInPage, - curTick, &dmaReadEvent); - - return; - } - - // set initial address - curAddr = curPrd.getBaseAddr(); - - // clear out the data buffer - memset(dataBuffer, 0, MAX_DMA_SIZE); - - // read the data from memory via DMA into a data buffer - while (bytesWritten < curPrd.getByteCount()) { - if (cmdBytesLeft <= 0) - panic("DMA data is larger than # of sectors specified\n"); - - dmaAddr = pciToDma(curAddr); - - // calculate how many bytes are in the current page - bytesLeft = curPrd.getByteCount() - bytesWritten; - bytesInPage = bytesInDmaPage(curAddr, bytesLeft); + uint32_t bytesWritten = 0; - // copy the data from memory into the data buffer - memcpy((void *)(dataBuffer + bytesWritten), - physmem->dma_addr(dmaAddr, bytesInPage), - bytesInPage); - - curAddr += bytesInPage; - bytesWritten += bytesInPage; - cmdBytesLeft -= bytesInPage; - } // write the data to the disk image - for (bytesWritten = 0; - bytesWritten < curPrd.getByteCount(); + for (bytesWritten = 0; bytesWritten < curPrd.getByteCount(); bytesWritten += SectorSize) { + cmdBytesLeft -= SectorSize; writeDisk(curSector++, (uint8_t *)(dataBuffer + bytesWritten)); } @@ -522,117 +408,55 @@ IdeDisk::dmaReadDone() } void -IdeDisk::doDmaWrite() +IdeDisk::doDmaDataWrite() { /** @todo we need to figure out what the delay actually will be */ Tick totalDiskDelay = diskDelay + (curPrd.getByteCount() / SectorSize); + uint32_t bytesRead = 0; DPRINTF(IdeDisk, "doDmaWrite, diskDelay: %d totalDiskDelay: %d\n", diskDelay, totalDiskDelay); - if (dmaInterface) { - if (dmaInterface->busy()) { - // reschedule after waiting period - dmaWriteWaitEvent.schedule(curTick + DMA_BACKOFF_PERIOD); - return; - } - - Addr dmaAddr = pciToDma(curPrd.getBaseAddr()); - - uint32_t bytesInPage = bytesInDmaPage(curPrd.getBaseAddr(), - (uint32_t)curPrd.getByteCount()); + memset(dataBuffer, 0, MAX_DMA_SIZE); + assert(cmdBytesLeft <= MAX_DMA_SIZE); + while (bytesRead < curPrd.getByteCount()) { + readDisk(curSector++, (uint8_t *)(dataBuffer + bytesRead)); + bytesRead += SectorSize; + cmdBytesLeft -= SectorSize; + } - dmaInterfaceBytes = bytesInPage; + dmaWriteWaitEvent.schedule(curTick + totalDiskDelay); +} - if (bytesInPage == TheISA::VMPageSize) - dmaWriteFullPages++; - dmaWriteBytes += bytesInPage; - dmaWriteTxs++; +void +IdeDisk::doDmaWrite() +{ - dmaInterface->doDMA(WriteInvalidate, dmaAddr, - bytesInPage, curTick + totalDiskDelay, - &dmaWriteEvent); + if (!dmaWriteCG) { + // clear out the data buffer + dmaWriteCG = new ChunkGenerator(curPrd.getBaseAddr(), + curPrd.getByteCount(), TheISA::PageBytes); + } + if (ctrl->dmaPending()) { + panic("shouldn't be reentant??"); + dmaWriteWaitEvent.schedule(curTick + DMA_BACKOFF_PERIOD); + return; + } else if (!dmaWriteCG->done()) { + assert(dmaWriteCG->complete() < MAX_DMA_SIZE); + ctrl->dmaWrite(pciToDma(dmaWriteCG->addr()), dmaWriteCG->size(), + &dmaWriteWaitEvent, dataBuffer + dmaWriteCG->complete()); + dmaWriteCG->next(); } else { - // schedule event with disk delay (dmaWriteDone) - dmaWriteEvent.schedule(curTick + totalDiskDelay); + assert(dmaWriteCG->done()); + delete dmaWriteCG; + dmaWriteCG = NULL; + dmaWriteDone(); } } void IdeDisk::dmaWriteDone() { - Addr curAddr = 0, pageAddr = 0, dmaAddr = 0; - uint32_t bytesRead = 0, bytesInPage = 0; - - // continue to use the DMA interface until all pages are read - if (dmaInterface && (dmaInterfaceBytes < curPrd.getByteCount())) { - // see if the interface is busy - if (dmaInterface->busy()) { - // reschedule after waiting period - dmaWriteEvent.schedule(curTick + DMA_BACKOFF_PERIOD); - return; - } - - uint32_t bytesLeft = curPrd.getByteCount() - dmaInterfaceBytes; - curAddr = curPrd.getBaseAddr() + dmaInterfaceBytes; - dmaAddr = pciToDma(curAddr); - - bytesInPage = bytesInDmaPage(curAddr, bytesLeft); - dmaInterfaceBytes += bytesInPage; - - if (bytesInPage == TheISA::VMPageSize) - dmaWriteFullPages++; - dmaWriteBytes += bytesInPage; - dmaWriteTxs++; - - dmaInterface->doDMA(WriteInvalidate, dmaAddr, - bytesInPage, curTick, - &dmaWriteEvent); - - return; - } - - // setup the initial page and DMA address - curAddr = curPrd.getBaseAddr(); - pageAddr = TheISA::TruncPage(curAddr); - dmaAddr = pciToDma(curAddr); - - // clear out the data buffer - memset(dataBuffer, 0, MAX_DMA_SIZE); - - while (bytesRead < curPrd.getByteCount()) { - // see if we have crossed into a new page - if (pageAddr != TheISA::TruncPage(curAddr)) { - // write the data to memory - memcpy(physmem->dma_addr(dmaAddr, bytesInPage), - (void *)(dataBuffer + (bytesRead - bytesInPage)), - bytesInPage); - - // update the DMA address and page address - pageAddr = TheISA::TruncPage(curAddr); - dmaAddr = pciToDma(curAddr); - - bytesInPage = 0; - } - - if (cmdBytesLeft <= 0) - panic("DMA requested data is larger than # sectors specified\n"); - - readDisk(curSector++, (uint8_t *)(dataBuffer + bytesRead)); - - curAddr += SectorSize; - bytesRead += SectorSize; - bytesInPage += SectorSize; - cmdBytesLeft -= SectorSize; - } - - // write the last page worth read to memory - if (bytesInPage != 0) { - memcpy(physmem->dma_addr(dmaAddr, bytesInPage), - (void *)(dataBuffer + (bytesRead - bytesInPage)), - bytesInPage); - } - // check for the EOT if (curPrd.getEOT()) { assert(cmdBytesLeft == 0); @@ -1188,13 +1012,13 @@ IdeDisk::serialize(ostream &os) SERIALIZE_SCALAR(curPrd.entry.endOfTable); SERIALIZE_SCALAR(curPrdAddr); + /** @todo need to serialized chunk generator stuff!! */ // Serialize current transfer related information SERIALIZE_SCALAR(cmdBytesLeft); SERIALIZE_SCALAR(cmdBytes); SERIALIZE_SCALAR(drqBytesLeft); SERIALIZE_SCALAR(curSector); SERIALIZE_SCALAR(dmaRead); - SERIALIZE_SCALAR(dmaInterfaceBytes); SERIALIZE_SCALAR(intrPending); SERIALIZE_ENUM(devState); SERIALIZE_ENUM(dmaState); @@ -1240,13 +1064,13 @@ IdeDisk::unserialize(Checkpoint *cp, const string §ion) UNSERIALIZE_SCALAR(curPrd.entry.endOfTable); UNSERIALIZE_SCALAR(curPrdAddr); + /** @todo need to serialized chunk generator stuff!! */ // Unserialize current transfer related information UNSERIALIZE_SCALAR(cmdBytes); UNSERIALIZE_SCALAR(cmdBytesLeft); UNSERIALIZE_SCALAR(drqBytesLeft); UNSERIALIZE_SCALAR(curSector); UNSERIALIZE_SCALAR(dmaRead); - UNSERIALIZE_SCALAR(dmaInterfaceBytes); UNSERIALIZE_SCALAR(intrPending); UNSERIALIZE_ENUM(devState); UNSERIALIZE_ENUM(dmaState); @@ -1260,7 +1084,6 @@ static const char *DriveID_strings[] = { "master", "slave" }; BEGIN_DECLARE_SIM_OBJECT_PARAMS(IdeDisk) SimObjectParam<DiskImage *> image; - SimObjectParam<PhysicalMemory *> physmem; SimpleEnumParam<DriveID> driveID; Param<int> delay; @@ -1269,7 +1092,6 @@ END_DECLARE_SIM_OBJECT_PARAMS(IdeDisk) BEGIN_INIT_SIM_OBJECT_PARAMS(IdeDisk) INIT_PARAM(image, "Disk image"), - INIT_PARAM(physmem, "Physical memory"), INIT_ENUM_PARAM(driveID, "Drive ID (0=master 1=slave)", DriveID_strings), INIT_PARAM_DFLT(delay, "Fixed disk delay in microseconds", 1) @@ -1278,7 +1100,7 @@ END_INIT_SIM_OBJECT_PARAMS(IdeDisk) CREATE_SIM_OBJECT(IdeDisk) { - return new IdeDisk(getInstanceName(), image, physmem, driveID, delay); + return new IdeDisk(getInstanceName(), image, driveID, delay); } REGISTER_SIM_OBJECT("IdeDisk", IdeDisk) diff --git a/dev/ide_disk.hh b/dev/ide_disk.hh index 402ae44ee..891c462b5 100644 --- a/dev/ide_disk.hh +++ b/dev/ide_disk.hh @@ -191,12 +191,8 @@ class IdeDisk : public SimObject protected: /** The IDE controller for this disk. */ IdeController *ctrl; - /** The DMA interface to use for transfers */ - DMAInterface<Bus> *dmaInterface; /** The image that contains the data of this disk. */ DiskImage *image; - /** Pointer to physical memory for DMA transfers */ - PhysicalMemory *physmem; protected: /** The disk delay in microseconds. */ @@ -231,8 +227,6 @@ class IdeDisk : public SimObject uint32_t curPrdAddr; /** PRD entry */ PrdTableEntry curPrd; - /** Number of bytes transfered by DMA interface for current transfer */ - uint32_t dmaInterfaceBytes; /** Device ID (master=0/slave=1) */ int devID; /** Interrupt pending */ @@ -250,12 +244,10 @@ class IdeDisk : public SimObject * Create and initialize this Disk. * @param name The name of this disk. * @param img The disk image of this disk. - * @param phys Pointer to physical memory * @param id The disk ID (master=0/slave=1) * @param disk_delay The disk delay in milliseconds */ - IdeDisk(const std::string &name, DiskImage *img, PhysicalMemory *phys, - int id, Tick disk_delay); + IdeDisk(const std::string &name, DiskImage *img, int id, Tick disk_delay); /** * Delete the data buffer. @@ -277,10 +269,9 @@ class IdeDisk : public SimObject * Set the controller for this device * @param c The IDE controller */ - void setController(IdeController *c, DMAInterface<Bus> *dmaIntr) { + void setController(IdeController *c) { if (ctrl) panic("Cannot change the controller once set!\n"); ctrl = c; - dmaInterface = dmaIntr; } // Device register read/write @@ -303,11 +294,17 @@ class IdeDisk : public SimObject friend class EventWrapper<IdeDisk, &IdeDisk::doDmaTransfer>; EventWrapper<IdeDisk, &IdeDisk::doDmaTransfer> dmaTransferEvent; + void doDmaDataRead(); + void doDmaRead(); + ChunkGenerator *dmaReadCG; friend class EventWrapper<IdeDisk, &IdeDisk::doDmaRead>; EventWrapper<IdeDisk, &IdeDisk::doDmaRead> dmaReadWaitEvent; + void doDmaDataWrite(); + void doDmaWrite(); + ChunkGenerator *dmaWriteCG; friend class EventWrapper<IdeDisk, &IdeDisk::doDmaWrite>; EventWrapper<IdeDisk, &IdeDisk::doDmaWrite> dmaWriteWaitEvent; @@ -353,8 +350,6 @@ class IdeDisk : public SimObject inline Addr pciToDma(Addr pciAddr); - uint32_t bytesInDmaPage(Addr curAddr, uint32_t bytesLeft); - /** * Serialize this object to the given output stream. * @param os The stream to serialize to. diff --git a/dev/io_device.cc b/dev/io_device.cc index 6ab876ab8..24f33d84d 100644 --- a/dev/io_device.cc +++ b/dev/io_device.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2005 The Regents of The University of Michigan + * Copyright (c) 2006 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,31 +27,213 @@ */ #include "dev/io_device.hh" -#include "mem/bus/base_interface.hh" -#include "mem/bus/dma_interface.hh" #include "sim/builder.hh" -PioDevice::PioDevice(const std::string &name, Platform *p) - : FunctionalMemory(name), platform(p), pioInterface(NULL), pioLatency(0) -{} + +PioPort::PioPort(PioDevice *dev, Platform *p) + : device(dev), platform(p) +{ } + + +Tick +PioPort::recvAtomic(Packet &pkt) +{ + return device->recvAtomic(pkt); +} + +void +PioPort::recvFunctional(Packet &pkt) +{ + device->recvAtomic(pkt); +} + +void +PioPort::getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) +{ + snoop.clear(); + device->addressRanges(resp); +} + + +Packet * +PioPort::recvRetry() +{ + Packet* pkt = transmitList.front(); + transmitList.pop_front(); + return pkt; +} + + +void +PioPort::SendEvent::process() +{ + if (port->Port::sendTiming(packet) == Success) + return; + + port->transmitList.push_back(&packet); +} + + +bool +PioPort::recvTiming(Packet &pkt) +{ + device->recvAtomic(pkt); + sendTiming(pkt, pkt.time-pkt.req->getTime()); + return Success; +} PioDevice::~PioDevice() { - if (pioInterface) - delete pioInterface; + if (pioPort) + delete pioPort; } -DEFINE_SIM_OBJECT_CLASS_NAME("PioDevice", PioDevice) +void +PioDevice::init() +{ + if (!pioPort) + panic("Pio port not connected to anything!"); + pioPort->sendStatusChange(Port::RangeChange); +} -DmaDevice::DmaDevice(const std::string &name, Platform *p) - : PioDevice(name, p), dmaInterface(NULL) -{} +void +BasicPioDevice::addressRanges(AddrRangeList &range_list) +{ + assert(pioSize != 0); + range_list.clear(); + range_list.push_back(RangeSize(pioAddr, pioSize)); +} + + +DmaPort::DmaPort(DmaDevice *dev, Platform *p) + : device(dev), platform(p), pendingCount(0) +{ } + +bool +DmaPort::recvTiming(Packet &pkt) +{ + if (pkt.senderState) { + DmaReqState *state; + state = (DmaReqState*)pkt.senderState; + state->completionEvent->schedule(pkt.time - pkt.req->getTime()); + delete pkt.req; + delete &pkt; + } else { + delete pkt.req; + delete &pkt; + } + + return Success; +} + +DmaDevice::DmaDevice(Params *p) + : PioDevice(p), dmaPort(NULL) +{ } + +void +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, Addr addr, int size, Event *event, + uint8_t *data) +{ + + assert(event); + + int prevSize = 0; + Packet basePkt; + Request baseReq(false); + + basePkt.flags = 0; + basePkt.coherence = NULL; + basePkt.senderState = NULL; + basePkt.src = 0; + basePkt.dest = 0; + basePkt.cmd = cmd; + basePkt.result = Unknown; + basePkt.req = NULL; +// baseReq.nicReq = true; + baseReq.setTime(curTick); + + for (ChunkGenerator gen(addr, size, peerBlockSize()); + !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->setPaddr(pkt->addr); + pkt->req->setSize(pkt->size); + // Increment the data pointer on a write + if (data) + pkt->dataStatic(data + prevSize) ; + prevSize += pkt->size; + // Set the last bit of the dma as the final packet for this dma + // and set it's completion event. + if (prevSize == size) { + DmaReqState *state = new DmaReqState(event, true); + + pkt->senderState = (void*)state; + } + assert(pendingCount >= 0); + pendingCount++; + sendDma(pkt); + } + // since this isn't getting used and we want a check to make sure that all + // packets had data in them at some point. + basePkt.dataStatic((uint8_t*)NULL); +} + + +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); + if (pkt->senderState) { + DmaReqState *state = (DmaReqState*)pkt->senderState; + state->completionEvent->schedule(curTick + (pkt->time - pkt->req->getTime()) +1); + } + pendingCount--; + assert(pendingCount >= 0); + delete pkt->req; + delete pkt; + +/* } else if (state == Functional) { + sendFunctional(pkt); + // Is this correct??? + 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; } -DEFINE_SIM_OBJECT_CLASS_NAME("DmaDevice", DmaDevice) diff --git a/dev/io_device.hh b/dev/io_device.hh index bcfd062b9..e492ccf0b 100644 --- a/dev/io_device.hh +++ b/dev/io_device.hh @@ -29,34 +29,307 @@ #ifndef __DEV_IO_DEVICE_HH__ #define __DEV_IO_DEVICE_HH__ -#include "mem/functional/functional.hh" +#include "base/chunk_generator.hh" +#include "mem/mem_object.hh" +#include "mem/packet_impl.hh" +#include "sim/eventq.hh" +#include "sim/sim_object.hh" -class BaseInterface; -class Bus; -class HierParams; class Platform; -template <class BusType> class DMAInterface; +class PioDevice; +class DmaDevice; +class System; -class PioDevice : public FunctionalMemory +/** + * 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. */ + Platform *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); + + virtual void recvFunctional(Packet &pkt) ; + + virtual void recvStatusChange(Status status) + { peerStatus = status; } + + virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop); + + /** + * 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; + 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; + }; + + /** 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, Platform *p); + + friend class PioPort::SendEvent; +}; + + +struct DmaReqState +{ + Event *completionEvent; + bool final; + DmaReqState(Event *ce, bool f) + : completionEvent(ce), final(f) + {} +}; + +class DmaPort : public Port { protected: + DmaDevice *device; + std::list<Packet*> transmitList; + + /** The platform that device/port are in. This is used to select which mode + * we are currently operating in. */ Platform *platform; - BaseInterface *pioInterface; - Tick pioLatency; + + /** Number of outstanding packets the dma port has. */ + int pendingCount; + + 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) + { panic("dma port shouldn't be used for pio access."); } + + virtual void recvStatusChange(Status status) + { ; } + + virtual Packet *recvRetry() ; + + virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) + { resp.clear(); snoop.clear(); } + + class SendEvent : public Event + { + DmaPort *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 DmaPort; + }; + + void sendDma(Packet *pkt); public: - PioDevice(const std::string &name, Platform *p); + DmaPort(DmaDevice *dev, Platform *p); + + void dmaAction(Command cmd, Addr addr, int size, Event *event, + uint8_t *data = NULL); + + bool dmaPending() { return pendingCount > 0; } + + 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 MemObject +{ + 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) = 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); } + + /** Pure virtual function that the device must implement. Called when a read + * command is recieved by the port. + * @param pkt Packet describing this request + * @return number of ticks it took to complete + */ + virtual Tick read(Packet &pkt) = 0; + + /** Pure virtual function that the device must implement. Called when a + * write command is recieved by the port. + * @param pkt Packet describing this request + * @return number of ticks it took to complete + */ + virtual Tick write(Packet &pkt) = 0; + + public: + /** Params struct which is extended through each device based on the + * parameters it needs. Since we are re-writing everything, we might as well + * start from the bottom this time. */ + + struct Params + { + std::string name; + Platform *platform; + System *system; + }; + + protected: + Params *_params; + + public: + const Params *params() const { return _params; } + + PioDevice(Params *p) + : MemObject(p->name), platform(p->platform), pioPort(NULL), + _params(p) + {} + virtual ~PioDevice(); + + virtual void init(); + + virtual Port *getPort(const std::string &if_name) + { + if (if_name == "pio") { + if (pioPort != NULL) + panic("pio port already connected to."); + pioPort = new PioPort(this, params()->platform); + return pioPort; + } else + return NULL; + } + friend class PioPort; + +}; + +class BasicPioDevice : public PioDevice +{ + public: + struct Params : public PioDevice::Params + { + Addr pio_addr; + Tick pio_delay; + }; + + protected: + /** Address that the device listens to. */ + Addr pioAddr; + + /** Size that the device's address range. */ + Addr pioSize; + + /** Delay that the device experinces on an access. */ + Tick pioDelay; + + public: + BasicPioDevice(Params *p) + : PioDevice(p), pioAddr(p->pio_addr), pioSize(0), pioDelay(p->pio_delay) + {} + + /** return the address ranges that this device responds to. + * @params range_list range list to populate with ranges + */ + void addressRanges(AddrRangeList &range_list); + }; class DmaDevice : public PioDevice { protected: - DMAInterface<Bus> *dmaInterface; + DmaPort *dmaPort; public: - DmaDevice(const std::string &name, Platform *p); + DmaDevice(Params *p); virtual ~DmaDevice(); + + void dmaWrite(Addr addr, int size, Event *event, uint8_t *data) + { dmaPort->dmaAction(Write, addr, size, event, data) ; } + + void dmaRead(Addr addr, int size, Event *event, uint8_t *data = NULL) + { dmaPort->dmaAction(Read, addr, size, event, data); } + + bool dmaPending() { return dmaPort->dmaPending(); } + + virtual Port *getPort(const std::string &if_name) + { + if (if_name == "pio") { + if (pioPort != NULL) + panic("pio port already connected to."); + pioPort = new PioPort(this, params()->platform); + return pioPort; + } else if (if_name == "dma") { + if (dmaPort != NULL) + panic("dma port already connected to."); + dmaPort = new DmaPort(this, params()->platform); + return dmaPort; + } else + return NULL; + } + + friend class DmaPort; }; + #endif // __DEV_IO_DEVICE_HH__ diff --git a/dev/isa_fake.cc b/dev/isa_fake.cc index 2afebbded..2f392a41a 100644 --- a/dev/isa_fake.cc +++ b/dev/isa_fake.cc @@ -35,106 +35,87 @@ #include <vector> #include "base/trace.hh" -#include "cpu/exec_context.hh" #include "dev/isa_fake.hh" -#include "mem/bus/bus.hh" -#include "mem/bus/pio_interface.hh" -#include "mem/bus/pio_interface_impl.hh" -#include "mem/functional/memory_control.hh" +#include "mem/packet.hh" #include "sim/builder.hh" #include "sim/system.hh" using namespace std; -using namespace TheISA; -IsaFake::IsaFake(const string &name, Addr a, MemoryController *mmu, - HierParams *hier, Bus *pio_bus, Addr size) - : PioDevice(name, NULL), addr(a) +IsaFake::IsaFake(Params *p) + : BasicPioDevice(p) { - mmu->add_child(this, RangeSize(addr, size)); - - if (pio_bus) { - pioInterface = newPioInterface(name + ".pio", hier, pio_bus, this, - &IsaFake::cacheAccess); - pioInterface->addAddrRange(RangeSize(addr, size)); - } + pioSize = p->pio_size; } -Fault -IsaFake::read(MemReqPtr &req, uint8_t *data) +Tick +IsaFake::read(Packet &pkt) { - DPRINTF(Tsunami, "read va=%#x size=%d\n", - req->vaddr, req->size); + assert(pkt.result == Unknown); + assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); -#if TRACING_ON - Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6; -#endif + pkt.time += pioDelay; - switch (req->size) { + DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt.addr, pkt.size); - case sizeof(uint64_t): - *(uint64_t*)data = 0xFFFFFFFFFFFFFFFFULL; - return NoFault; + switch (pkt.size) { + pkt.set(0xFFFFFFFFFFFFFFFFULL); + break; case sizeof(uint32_t): - *(uint32_t*)data = 0xFFFFFFFF; - return NoFault; + pkt.set((uint32_t)0xFFFFFFFF); + break; case sizeof(uint16_t): - *(uint16_t*)data = 0xFFFF; - return NoFault; + pkt.set((uint16_t)0xFFFF); + break; case sizeof(uint8_t): - *(uint8_t*)data = 0xFF; - return NoFault; - + pkt.set((uint8_t)0xFF); + break; default: panic("invalid access size(?) for PCI configspace!\n"); } - DPRINTFN("Isa FakeSMC ERROR: read daddr=%#x size=%d\n", daddr, req->size); - - return NoFault; -} - -Fault -IsaFake::write(MemReqPtr &req, const uint8_t *data) -{ - DPRINTF(Tsunami, "write - va=%#x size=%d \n", - req->vaddr, req->size); - - //:Addr daddr = (req->paddr & addr_mask) >> 6; - - return NoFault; + pkt.result = Success; + return pioDelay; } Tick -IsaFake::cacheAccess(MemReqPtr &req) +IsaFake::write(Packet &pkt) { - return curTick; + pkt.time += pioDelay; + DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt.addr, pkt.size); + pkt.result = Success; + return pioDelay; } BEGIN_DECLARE_SIM_OBJECT_PARAMS(IsaFake) - SimObjectParam<MemoryController *> mmu; - Param<Addr> addr; - SimObjectParam<Bus*> pio_bus; + Param<Addr> pio_addr; Param<Tick> pio_latency; - SimObjectParam<HierParams *> hier; - Param<Addr> size; + Param<Addr> pio_size; + SimObjectParam<Platform *> platform; + SimObjectParam<System *> system; END_DECLARE_SIM_OBJECT_PARAMS(IsaFake) BEGIN_INIT_SIM_OBJECT_PARAMS(IsaFake) - INIT_PARAM(mmu, "Memory Controller"), - INIT_PARAM(addr, "Device Address"), - INIT_PARAM_DFLT(pio_bus, "The IO Bus to attach to", NULL), - INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000), - INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams), - INIT_PARAM_DFLT(size, "Size of address range", 0x8) + INIT_PARAM(pio_addr, "Device Address"), + INIT_PARAM(pio_latency, "Programmed IO latency"), + INIT_PARAM(pio_size, "Size of address range"), + INIT_PARAM(platform, "platform"), + INIT_PARAM(system, "system object") END_INIT_SIM_OBJECT_PARAMS(IsaFake) CREATE_SIM_OBJECT(IsaFake) { - return new IsaFake(getInstanceName(), addr, mmu, hier, pio_bus, size); + IsaFake::Params *p = new IsaFake::Params; + p->name = getInstanceName(); + p->pio_addr = pio_addr; + p->pio_delay = pio_latency; + p->pio_size = pio_size; + p->platform = platform; + p->system = system; + return new IsaFake(p); } REGISTER_SIM_OBJECT("IsaFake", IsaFake) diff --git a/dev/isa_fake.hh b/dev/isa_fake.hh index 73e40c681..29050833d 100644 --- a/dev/isa_fake.hh +++ b/dev/isa_fake.hh @@ -37,51 +37,42 @@ #include "base/range.hh" #include "dev/io_device.hh" -class MemoryController; - /** * IsaFake is a device that returns -1 on all reads and * accepts all writes. It is meant to be placed at an address range * so that an mcheck doesn't occur when an os probes a piece of hw * that doesn't exist (e.g. UARTs1-3). */ -class IsaFake : public PioDevice +class IsaFake : public BasicPioDevice { - private: - /** The address in memory that we respond to */ - Addr addr; + public: + struct Params : public BasicPioDevice::Params + { + Addr pio_size; + }; + protected: + const Params *params() const { return (const Params*)_params; } public: /** * The constructor for Tsunmami Fake just registers itself with the MMU. - * @param name name of this device. - * @param a address to respond to. - * @param mmu the mmu we register with. - * @param size number of addresses to respond to + * @param p params structure */ - IsaFake(const std::string &name, Addr a, MemoryController *mmu, - HierParams *hier, Bus *pio_bus, Addr size = 0x8); + IsaFake(Params *p); /** * This read always returns -1. * @param req The memory request. * @param data Where to put the data. */ - virtual Fault read(MemReqPtr &req, uint8_t *data); + virtual Tick read(Packet &pkt); /** * All writes are simply ignored. * @param req The memory request. * @param data the data to not write. */ - virtual Fault write(MemReqPtr &req, const uint8_t *data); - - /** - * Return how long this access will take. - * @param req the memory request to calcuate - * @return Tick when the request is done - */ - Tick cacheAccess(MemReqPtr &req); + virtual Tick write(Packet &pkt); }; -#endif // __ISA_FAKE_HH__ +#endif // __TSUNAMI_FAKE_HH__ diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc index ed8c794f9..a2e224ed0 100644 --- a/dev/ns_gige.cc +++ b/dev/ns_gige.cc @@ -34,22 +34,18 @@ #include <deque> #include <string> +#include "arch/alpha/ev5.hh" #include "base/inet.hh" #include "cpu/exec_context.hh" #include "dev/etherlink.hh" #include "dev/ns_gige.hh" #include "dev/pciconfigall.hh" -#include "mem/bus/bus.hh" -#include "mem/bus/dma_interface.hh" -#include "mem/bus/pio_interface.hh" -#include "mem/bus/pio_interface_impl.hh" -#include "mem/functional/memory_control.hh" -#include "mem/functional/physical.hh" +#include "mem/packet.hh" #include "sim/builder.hh" #include "sim/debug.hh" #include "sim/host.hh" #include "sim/stats.hh" -#include "arch/vtophys.hh" +#include "sim/system.hh" const char *NsRxStateStrings[] = { @@ -107,29 +103,9 @@ NSGigE::NSGigE(Params *p) txEvent(this), rxFilterEnable(p->rx_filter), acceptBroadcast(false), acceptMulticast(false), acceptUnicast(false), acceptPerfect(false), acceptArp(false), multicastHashEnable(false), - physmem(p->pmem), intrTick(0), cpuPendingIntr(false), + intrTick(0), cpuPendingIntr(false), intrEvent(0), interface(0) { - if (p->pio_bus) { - pioInterface = newPioInterface(name() + ".pio", p->hier, - p->pio_bus, this, - &NSGigE::cacheAccess); - pioLatency = p->pio_latency * p->pio_bus->clockRate; - } - - if (p->header_bus) { - if (p->payload_bus) - dmaInterface = new DMAInterface<Bus>(name() + ".dma", - p->header_bus, - p->payload_bus, 1, - p->dma_no_allocate); - else - dmaInterface = new DMAInterface<Bus>(name() + ".dma", - p->header_bus, - p->header_bus, 1, - p->dma_no_allocate); - } else if (p->payload_bus) - panic("Must define a header bus if defining a payload bus"); intrDelay = p->intr_delay; dmaReadDelay = p->dma_read_delay; @@ -483,30 +459,18 @@ NSGigE::regStats() rxPacketRate = rxPackets / simSeconds; } -/** - * This is to read the PCI general configuration registers - */ -void -NSGigE::readConfig(int offset, int size, uint8_t *data) -{ - if (offset < PCI_DEVICE_SPECIFIC) - PciDev::readConfig(offset, size, data); - else - panic("Device specific PCI config space not implemented!\n"); -} /** * This is to write to the PCI general configuration registers */ void -NSGigE::writeConfig(int offset, int size, const uint8_t* data) +NSGigE::writeConfig(int offset, const uint16_t data) { if (offset < PCI_DEVICE_SPECIFIC) - PciDev::writeConfig(offset, size, data); + PciDev::writeConfig(offset, data); else panic("Device specific PCI config space not implemented!\n"); - // Need to catch writes to BARs to update the PIO interface switch (offset) { // seems to work fine without all these PCI settings, but i // put in the IO to double check, an assertion will fail if we @@ -516,39 +480,6 @@ NSGigE::writeConfig(int offset, int size, const uint8_t* data) ioEnable = true; else ioEnable = false; - -#if 0 - if (config.data[offset] & PCI_CMD_BME) { - bmEnabled = true; - } - else { - bmEnabled = false; - } - - if (config.data[offset] & PCI_CMD_MSE) { - memEnable = true; - } - else { - memEnable = false; - } -#endif - break; - - case PCI0_BASE_ADDR0: - if (BARAddrs[0] != 0) { - if (pioInterface) - pioInterface->addAddrRange(RangeSize(BARAddrs[0], BARSize[0])); - - BARAddrs[0] &= EV5::PAddrUncachedMask; - } - break; - case PCI0_BASE_ADDR1: - if (BARAddrs[1] != 0) { - if (pioInterface) - pioInterface->addAddrRange(RangeSize(BARAddrs[1], BARSize[1])); - - BARAddrs[1] &= EV5::PAddrUncachedMask; - } break; } } @@ -557,15 +488,18 @@ NSGigE::writeConfig(int offset, int size, const uint8_t* data) * This reads the device registers, which are detailed in the NS83820 * spec sheet */ -Fault -NSGigE::read(MemReqPtr &req, uint8_t *data) +Tick +NSGigE::read(Packet &pkt) { assert(ioEnable); + pkt.time += pioDelay; + pkt.allocate(); + //The mask is to give you only the offset into the device register file - Addr daddr = req->paddr & 0xfff; - DPRINTF(EthernetPIO, "read da=%#x pa=%#x va=%#x size=%d\n", - daddr, req->paddr, req->vaddr, req->size); + Addr daddr = pkt.addr & 0xfff; + DPRINTF(EthernetPIO, "read da=%#x pa=%#x size=%d\n", + daddr, pkt.addr, pkt.size); // there are some reserved registers, you can see ns_gige_reg.h and @@ -573,240 +507,246 @@ NSGigE::read(MemReqPtr &req, uint8_t *data) if (daddr > LAST && daddr <= RESERVED) { panic("Accessing reserved register"); } else if (daddr > RESERVED && daddr <= 0x3FC) { - readConfig(daddr & 0xff, req->size, data); - return NoFault; + if (pkt.size == sizeof(uint8_t)) + readConfig(daddr & 0xff, pkt.getPtr<uint8_t>()); + if (pkt.size == sizeof(uint16_t)) + readConfig(daddr & 0xff, pkt.getPtr<uint16_t>()); + if (pkt.size == sizeof(uint32_t)) + readConfig(daddr & 0xff, pkt.getPtr<uint32_t>()); + pkt.result = Success; + return pioDelay; } else if (daddr >= MIB_START && daddr <= MIB_END) { // don't implement all the MIB's. hopefully the kernel // doesn't actually DEPEND upon their values // MIB are just hardware stats keepers - uint32_t ® = *(uint32_t *) data; - reg = 0; - return NoFault; + pkt.set<uint32_t>(0); + pkt.result = Success; + return pioDelay; } else if (daddr > 0x3FC) panic("Something is messed up!\n"); - switch (req->size) { - case sizeof(uint32_t): - { - uint32_t ® = *(uint32_t *)data; - uint16_t rfaddr; - - switch (daddr) { - case CR: - reg = regs.command; - //these are supposed to be cleared on a read - reg &= ~(CR_RXD | CR_TXD | CR_TXR | CR_RXR); - break; + assert(pkt.size == sizeof(uint32_t)); + uint32_t ® = *pkt.getPtr<uint32_t>(); + uint16_t rfaddr; - case CFGR: - reg = regs.config; - break; + switch (daddr) { + case CR: + reg = regs.command; + //these are supposed to be cleared on a read + reg &= ~(CR_RXD | CR_TXD | CR_TXR | CR_RXR); + break; - case MEAR: - reg = regs.mear; - break; + case CFGR: + reg = regs.config; + break; - case PTSCR: - reg = regs.ptscr; - break; + case MEAR: + reg = regs.mear; + break; - case ISR: - reg = regs.isr; - devIntrClear(ISR_ALL); - break; + case PTSCR: + reg = regs.ptscr; + break; - case IMR: - reg = regs.imr; - break; + case ISR: + reg = regs.isr; + devIntrClear(ISR_ALL); + break; - case IER: - reg = regs.ier; - break; + case IMR: + reg = regs.imr; + break; - case IHR: - reg = regs.ihr; - break; + case IER: + reg = regs.ier; + break; - case TXDP: - reg = regs.txdp; - break; + case IHR: + reg = regs.ihr; + break; - case TXDP_HI: - reg = regs.txdp_hi; - break; + case TXDP: + reg = regs.txdp; + break; - case TX_CFG: - reg = regs.txcfg; - break; + case TXDP_HI: + reg = regs.txdp_hi; + break; - case GPIOR: - reg = regs.gpior; - break; + case TX_CFG: + reg = regs.txcfg; + break; - case RXDP: - reg = regs.rxdp; - break; + case GPIOR: + reg = regs.gpior; + break; - case RXDP_HI: - reg = regs.rxdp_hi; - break; + case RXDP: + reg = regs.rxdp; + break; - case RX_CFG: - reg = regs.rxcfg; - break; + case RXDP_HI: + reg = regs.rxdp_hi; + break; - case PQCR: - reg = regs.pqcr; - break; + case RX_CFG: + reg = regs.rxcfg; + break; - case WCSR: - reg = regs.wcsr; - break; + case PQCR: + reg = regs.pqcr; + break; - case PCR: - reg = regs.pcr; - break; + case WCSR: + reg = regs.wcsr; + break; + + case PCR: + reg = regs.pcr; + break; + + // see the spec sheet for how RFCR and RFDR work + // basically, you write to RFCR to tell the machine + // what you want to do next, then you act upon RFDR, + // and the device will be prepared b/c of what you + // wrote to RFCR + case RFCR: + reg = regs.rfcr; + break; - // see the spec sheet for how RFCR and RFDR work - // basically, you write to RFCR to tell the machine - // what you want to do next, then you act upon RFDR, - // and the device will be prepared b/c of what you - // wrote to RFCR - case RFCR: - reg = regs.rfcr; + case RFDR: + rfaddr = (uint16_t)(regs.rfcr & RFCR_RFADDR); + switch (rfaddr) { + // Read from perfect match ROM octets + case 0x000: + reg = rom.perfectMatch[1]; + reg = reg << 8; + reg += rom.perfectMatch[0]; + break; + case 0x002: + reg = rom.perfectMatch[3] << 8; + reg += rom.perfectMatch[2]; break; + case 0x004: + reg = rom.perfectMatch[5] << 8; + reg += rom.perfectMatch[4]; + break; + default: + // Read filter hash table + if (rfaddr >= FHASH_ADDR && + rfaddr < FHASH_ADDR + FHASH_SIZE) { - case RFDR: - rfaddr = (uint16_t)(regs.rfcr & RFCR_RFADDR); - switch (rfaddr) { - // Read from perfect match ROM octets - case 0x000: - reg = rom.perfectMatch[1]; - reg = reg << 8; - reg += rom.perfectMatch[0]; - break; - case 0x002: - reg = rom.perfectMatch[3] << 8; - reg += rom.perfectMatch[2]; - break; - case 0x004: - reg = rom.perfectMatch[5] << 8; - reg += rom.perfectMatch[4]; - break; - default: - // Read filter hash table - if (rfaddr >= FHASH_ADDR && - rfaddr < FHASH_ADDR + FHASH_SIZE) { - - // Only word-aligned reads supported - if (rfaddr % 2) - panic("unaligned read from filter hash table!"); - - reg = rom.filterHash[rfaddr - FHASH_ADDR + 1] << 8; - reg += rom.filterHash[rfaddr - FHASH_ADDR]; - break; - } + // Only word-aligned reads supported + if (rfaddr % 2) + panic("unaligned read from filter hash table!"); - panic("reading RFDR for something other than pattern" - " matching or hashing! %#x\n", rfaddr); + reg = rom.filterHash[rfaddr - FHASH_ADDR + 1] << 8; + reg += rom.filterHash[rfaddr - FHASH_ADDR]; + break; } - break; - case SRR: - reg = regs.srr; - break; + panic("reading RFDR for something other than pattern" + " matching or hashing! %#x\n", rfaddr); + } + break; - case MIBC: - reg = regs.mibc; - reg &= ~(MIBC_MIBS | MIBC_ACLR); - break; + case SRR: + reg = regs.srr; + break; - case VRCR: - reg = regs.vrcr; - break; + case MIBC: + reg = regs.mibc; + reg &= ~(MIBC_MIBS | MIBC_ACLR); + break; - case VTCR: - reg = regs.vtcr; - break; + case VRCR: + reg = regs.vrcr; + break; - case VDR: - reg = regs.vdr; - break; + case VTCR: + reg = regs.vtcr; + break; - case CCSR: - reg = regs.ccsr; - break; + case VDR: + reg = regs.vdr; + break; - case TBICR: - reg = regs.tbicr; - break; + case CCSR: + reg = regs.ccsr; + break; - case TBISR: - reg = regs.tbisr; - break; + case TBICR: + reg = regs.tbicr; + break; - case TANAR: - reg = regs.tanar; - break; + case TBISR: + reg = regs.tbisr; + break; - case TANLPAR: - reg = regs.tanlpar; - break; + case TANAR: + reg = regs.tanar; + break; - case TANER: - reg = regs.taner; - break; + case TANLPAR: + reg = regs.tanlpar; + break; - case TESR: - reg = regs.tesr; - break; + case TANER: + reg = regs.taner; + break; - case M5REG: - reg = 0; - if (params()->rx_thread) - reg |= M5REG_RX_THREAD; - if (params()->tx_thread) - reg |= M5REG_TX_THREAD; - if (params()->rss) - reg |= M5REG_RSS; - break; + case TESR: + reg = regs.tesr; + break; - default: - panic("reading unimplemented register: addr=%#x", daddr); - } + case M5REG: + reg = 0; + if (params()->rx_thread) + reg |= M5REG_RX_THREAD; + if (params()->tx_thread) + reg |= M5REG_TX_THREAD; + if (params()->rss) + reg |= M5REG_RSS; + break; - DPRINTF(EthernetPIO, "read from %#x: data=%d data=%#x\n", - daddr, reg, reg); + default: + panic("reading unimplemented register: addr=%#x", daddr); } - break; - default: - panic("accessing register with invalid size: addr=%#x, size=%d", - daddr, req->size); - } + DPRINTF(EthernetPIO, "read from %#x: data=%d data=%#x\n", + daddr, reg, reg); - return NoFault; + pkt.result = Success; + return pioDelay; } -Fault -NSGigE::write(MemReqPtr &req, const uint8_t *data) +Tick +NSGigE::write(Packet &pkt) { assert(ioEnable); - Addr daddr = req->paddr & 0xfff; - DPRINTF(EthernetPIO, "write da=%#x pa=%#x va=%#x size=%d\n", - daddr, req->paddr, req->vaddr, req->size); + Addr daddr = pkt.addr & 0xfff; + DPRINTF(EthernetPIO, "write da=%#x pa=%#x size=%d\n", + daddr, pkt.addr, pkt.size); + + pkt.time += pioDelay; if (daddr > LAST && daddr <= RESERVED) { panic("Accessing reserved register"); } else if (daddr > RESERVED && daddr <= 0x3FC) { - writeConfig(daddr & 0xff, req->size, data); - return NoFault; + if (pkt.size == sizeof(uint8_t)) + writeConfig(daddr & 0xff, pkt.get<uint8_t>()); + if (pkt.size == sizeof(uint16_t)) + writeConfig(daddr & 0xff, pkt.get<uint16_t>()); + if (pkt.size == sizeof(uint32_t)) + writeConfig(daddr & 0xff, pkt.get<uint32_t>()); + pkt.result = Success; + return pioDelay; } else if (daddr > 0x3FC) panic("Something is messed up!\n"); - if (req->size == sizeof(uint32_t)) { - uint32_t reg = *(uint32_t *)data; + if (pkt.size == sizeof(uint32_t)) { + uint32_t reg = pkt.get<uint32_t>(); uint16_t rfaddr; DPRINTF(EthernetPIO, "write data=%d data=%#x\n", reg, reg); @@ -1192,8 +1132,8 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data) } else { panic("Invalid Request Size"); } - - return NoFault; + pkt.result = Success; + return pioDelay; } void @@ -1443,42 +1383,17 @@ NSGigE::regsReset() acceptArp = false; } -void -NSGigE::rxDmaReadCopy() -{ - assert(rxDmaState == dmaReading); - - physmem->dma_read((uint8_t *)rxDmaData, rxDmaAddr, rxDmaLen); - rxDmaState = dmaIdle; - - DPRINTF(EthernetDMA, "rx dma read paddr=%#x len=%d\n", - rxDmaAddr, rxDmaLen); - DDUMP(EthernetDMA, rxDmaData, rxDmaLen); -} - bool NSGigE::doRxDmaRead() { assert(rxDmaState == dmaIdle || rxDmaState == dmaReadWaiting); rxDmaState = dmaReading; - if (dmaInterface && !rxDmaFree) { - if (dmaInterface->busy()) - rxDmaState = dmaReadWaiting; - else - dmaInterface->doDMA(Read, rxDmaAddr, rxDmaLen, curTick, - &rxDmaReadEvent, true); - return true; - } - - if (dmaReadDelay == 0 && dmaReadFactor == 0) { - rxDmaReadCopy(); - return false; - } + if (dmaPending()) + rxDmaState = dmaReadWaiting; + else + dmaRead(rxDmaAddr, rxDmaLen, &rxDmaReadEvent, (uint8_t*)rxDmaData); - Tick factor = ((rxDmaLen + ULL(63)) >> ULL(6)) * dmaReadFactor; - Tick start = curTick + dmaReadDelay + factor; - rxDmaReadEvent.schedule(start); return true; } @@ -1486,7 +1401,11 @@ void NSGigE::rxDmaReadDone() { assert(rxDmaState == dmaReading); - rxDmaReadCopy(); + rxDmaState = dmaIdle; + + DPRINTF(EthernetDMA, "rx dma read paddr=%#x len=%d\n", + rxDmaAddr, rxDmaLen); + DDUMP(EthernetDMA, rxDmaData, rxDmaLen); // If the transmit state machine has a pending DMA, let it go first if (txDmaState == dmaReadWaiting || txDmaState == dmaWriteWaiting) @@ -1495,42 +1414,16 @@ NSGigE::rxDmaReadDone() rxKick(); } -void -NSGigE::rxDmaWriteCopy() -{ - assert(rxDmaState == dmaWriting); - - physmem->dma_write(rxDmaAddr, (uint8_t *)rxDmaData, rxDmaLen); - rxDmaState = dmaIdle; - - DPRINTF(EthernetDMA, "rx dma write paddr=%#x len=%d\n", - rxDmaAddr, rxDmaLen); - DDUMP(EthernetDMA, rxDmaData, rxDmaLen); -} - bool NSGigE::doRxDmaWrite() { assert(rxDmaState == dmaIdle || rxDmaState == dmaWriteWaiting); rxDmaState = dmaWriting; - if (dmaInterface && !rxDmaFree) { - if (dmaInterface->busy()) - rxDmaState = dmaWriteWaiting; - else - dmaInterface->doDMA(WriteInvalidate, rxDmaAddr, rxDmaLen, curTick, - &rxDmaWriteEvent, true); - return true; - } - - if (dmaWriteDelay == 0 && dmaWriteFactor == 0) { - rxDmaWriteCopy(); - return false; - } - - Tick factor = ((rxDmaLen + ULL(63)) >> ULL(6)) * dmaWriteFactor; - Tick start = curTick + dmaWriteDelay + factor; - rxDmaWriteEvent.schedule(start); + if (dmaPending()) + rxDmaState = dmaWriteWaiting; + else + dmaWrite(rxDmaAddr, rxDmaLen, &rxDmaWriteEvent, (uint8_t*)rxDmaData); return true; } @@ -1538,7 +1431,11 @@ void NSGigE::rxDmaWriteDone() { assert(rxDmaState == dmaWriting); - rxDmaWriteCopy(); + rxDmaState = dmaIdle; + + DPRINTF(EthernetDMA, "rx dma write paddr=%#x len=%d\n", + rxDmaAddr, rxDmaLen); + DDUMP(EthernetDMA, rxDmaData, rxDmaLen); // If the transmit state machine has a pending DMA, let it go first if (txDmaState == dmaReadWaiting || txDmaState == dmaWriteWaiting) @@ -1935,42 +1832,17 @@ NSGigE::transmit() } } -void -NSGigE::txDmaReadCopy() -{ - assert(txDmaState == dmaReading); - - physmem->dma_read((uint8_t *)txDmaData, txDmaAddr, txDmaLen); - txDmaState = dmaIdle; - - DPRINTF(EthernetDMA, "tx dma read paddr=%#x len=%d\n", - txDmaAddr, txDmaLen); - DDUMP(EthernetDMA, txDmaData, txDmaLen); -} - bool NSGigE::doTxDmaRead() { assert(txDmaState == dmaIdle || txDmaState == dmaReadWaiting); txDmaState = dmaReading; - if (dmaInterface && !txDmaFree) { - if (dmaInterface->busy()) - txDmaState = dmaReadWaiting; - else - dmaInterface->doDMA(Read, txDmaAddr, txDmaLen, curTick, - &txDmaReadEvent, true); - return true; - } - - if (dmaReadDelay == 0 && dmaReadFactor == 0.0) { - txDmaReadCopy(); - return false; - } + if (dmaPending()) + txDmaState = dmaReadWaiting; + else + dmaRead(txDmaAddr, txDmaLen, &txDmaReadEvent, (uint8_t*)txDmaData); - Tick factor = ((txDmaLen + ULL(63)) >> ULL(6)) * dmaReadFactor; - Tick start = curTick + dmaReadDelay + factor; - txDmaReadEvent.schedule(start); return true; } @@ -1978,7 +1850,11 @@ void NSGigE::txDmaReadDone() { assert(txDmaState == dmaReading); - txDmaReadCopy(); + txDmaState = dmaIdle; + + DPRINTF(EthernetDMA, "tx dma read paddr=%#x len=%d\n", + txDmaAddr, txDmaLen); + DDUMP(EthernetDMA, txDmaData, txDmaLen); // If the receive state machine has a pending DMA, let it go first if (rxDmaState == dmaReadWaiting || rxDmaState == dmaWriteWaiting) @@ -1987,42 +1863,16 @@ NSGigE::txDmaReadDone() txKick(); } -void -NSGigE::txDmaWriteCopy() -{ - assert(txDmaState == dmaWriting); - - physmem->dma_write(txDmaAddr, (uint8_t *)txDmaData, txDmaLen); - txDmaState = dmaIdle; - - DPRINTF(EthernetDMA, "tx dma write paddr=%#x len=%d\n", - txDmaAddr, txDmaLen); - DDUMP(EthernetDMA, txDmaData, txDmaLen); -} - bool NSGigE::doTxDmaWrite() { assert(txDmaState == dmaIdle || txDmaState == dmaWriteWaiting); txDmaState = dmaWriting; - if (dmaInterface && !txDmaFree) { - if (dmaInterface->busy()) - txDmaState = dmaWriteWaiting; - else - dmaInterface->doDMA(WriteInvalidate, txDmaAddr, txDmaLen, curTick, - &txDmaWriteEvent, true); - return true; - } - - if (dmaWriteDelay == 0 && dmaWriteFactor == 0.0) { - txDmaWriteCopy(); - return false; - } - - Tick factor = ((txDmaLen + ULL(63)) >> ULL(6)) * dmaWriteFactor; - Tick start = curTick + dmaWriteDelay + factor; - txDmaWriteEvent.schedule(start); + if (dmaPending()) + txDmaState = dmaWriteWaiting; + else + dmaWrite(txDmaAddr, txDmaLen, &txDmaWriteEvent, (uint8_t*)txDmaData); return true; } @@ -2030,7 +1880,11 @@ void NSGigE::txDmaWriteDone() { assert(txDmaState == dmaWriting); - txDmaWriteCopy(); + txDmaState = dmaIdle; + + DPRINTF(EthernetDMA, "tx dma write paddr=%#x len=%d\n", + txDmaAddr, txDmaLen); + DDUMP(EthernetDMA, txDmaData, txDmaLen); // If the receive state machine has a pending DMA, let it go first if (rxDmaState == dmaReadWaiting || rxDmaState == dmaWriteWaiting) @@ -2147,7 +2001,7 @@ NSGigE::txKick() case txFifoBlock: if (!txPacket) { DPRINTF(EthernetSM, "****starting the tx of a new packet****\n"); - txPacket = new PacketData(16384); + txPacket = new EthPacketData(16384); txPacketBufPtr = txPacket->data; } @@ -2473,7 +2327,7 @@ NSGigE::transferDone() } bool -NSGigE::rxFilter(const PacketPtr &packet) +NSGigE::rxFilter(const EthPacketPtr &packet) { EthPtr eth = packet; bool drop = true; @@ -2516,7 +2370,7 @@ NSGigE::rxFilter(const PacketPtr &packet) } bool -NSGigE::recvPacket(PacketPtr packet) +NSGigE::recvPacket(EthPacketPtr packet) { rxBytes += packet->length; rxPackets++; @@ -2576,14 +2430,7 @@ NSGigE::serialize(ostream &os) /* * Finalize any DMA events now. */ - if (rxDmaReadEvent.scheduled()) - rxDmaReadCopy(); - if (rxDmaWriteEvent.scheduled()) - rxDmaWriteCopy(); - if (txDmaReadEvent.scheduled()) - txDmaReadCopy(); - if (txDmaWriteEvent.scheduled()) - txDmaWriteCopy(); + // @todo will mem system save pending dma? /* * Serialize the device registers @@ -2804,7 +2651,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion) bool txPacketExists; UNSERIALIZE_SCALAR(txPacketExists); if (txPacketExists) { - txPacket = new PacketData(16384); + txPacket = new EthPacketData(16384); txPacket->unserialize("txPacket", cp, section); uint32_t txPktBufPtr; UNSERIALIZE_SCALAR(txPktBufPtr); @@ -2816,7 +2663,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(rxPacketExists); rxPacket = 0; if (rxPacketExists) { - rxPacket = new PacketData(16384); + rxPacket = new EthPacketData(16384); rxPacket->unserialize("rxPacket", cp, section); uint32_t rxPktBufPtr; UNSERIALIZE_SCALAR(rxPktBufPtr); @@ -2925,23 +2772,6 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion) intrEvent = new IntrEvent(this, true); intrEvent->schedule(intrEventTick); } - - /* - * re-add addrRanges to bus bridges - */ - if (pioInterface) { - pioInterface->addAddrRange(RangeSize(BARAddrs[0], BARSize[0])); - pioInterface->addAddrRange(RangeSize(BARAddrs[1], BARSize[1])); - } -} - -Tick -NSGigE::cacheAccess(MemReqPtr &req) -{ - DPRINTF(EthernetPIO, "timing access to paddr=%#x (daddr=%#x)\n", - req->paddr, req->paddr & 0xfff); - - return curTick + pioLatency; } BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt) @@ -2976,22 +2806,16 @@ REGISTER_SIM_OBJECT("NSGigEInt", NSGigEInt) BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE) - Param<Tick> clock; - - Param<Addr> addr; - SimObjectParam<MemoryController *> mmu; - SimObjectParam<PhysicalMemory *> physmem; + SimObjectParam<System *> system; + SimObjectParam<Platform *> platform; SimObjectParam<PciConfigAll *> configspace; SimObjectParam<PciConfigData *> configdata; - SimObjectParam<Platform *> platform; Param<uint32_t> pci_bus; Param<uint32_t> pci_dev; Param<uint32_t> pci_func; + Param<Tick> pio_latency; - SimObjectParam<HierParams *> hier; - SimObjectParam<Bus*> pio_bus; - SimObjectParam<Bus*> dma_bus; - SimObjectParam<Bus*> payload_bus; + Param<Tick> clock; Param<bool> dma_desc_free; Param<bool> dma_data_free; Param<Tick> dma_read_delay; @@ -2999,7 +2823,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE) Param<Tick> dma_read_factor; Param<Tick> dma_write_factor; Param<bool> dma_no_allocate; - Param<Tick> pio_latency; Param<Tick> intr_delay; Param<Tick> rx_delay; @@ -3017,22 +2840,16 @@ END_DECLARE_SIM_OBJECT_PARAMS(NSGigE) BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE) - INIT_PARAM(clock, "State machine processor frequency"), - - INIT_PARAM(addr, "Device Address"), - INIT_PARAM(mmu, "Memory Controller"), - INIT_PARAM(physmem, "Physical Memory"), + INIT_PARAM(system, "System pointer"), + INIT_PARAM(platform, "Platform pointer"), INIT_PARAM(configspace, "PCI Configspace"), INIT_PARAM(configdata, "PCI Config data"), - INIT_PARAM(platform, "Platform"), - INIT_PARAM(pci_bus, "PCI bus"), + INIT_PARAM(pci_bus, "PCI bus ID"), INIT_PARAM(pci_dev, "PCI device number"), INIT_PARAM(pci_func, "PCI function code"), + INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1), + INIT_PARAM(clock, "State machine cycle time"), - INIT_PARAM(hier, "Hierarchy global variables"), - INIT_PARAM(pio_bus, ""), - INIT_PARAM(dma_bus, ""), - INIT_PARAM(payload_bus, "The IO Bus to attach to for payload"), INIT_PARAM(dma_desc_free, "DMA of Descriptors is free"), INIT_PARAM(dma_data_free, "DMA of Data is free"), INIT_PARAM(dma_read_delay, "fixed delay for dma reads"), @@ -3040,7 +2857,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE) INIT_PARAM(dma_read_factor, "multiplier for dma reads"), INIT_PARAM(dma_write_factor, "multiplier for dma writes"), INIT_PARAM(dma_no_allocate, "Should DMA reads allocate cache lines"), - INIT_PARAM(pio_latency, "Programmed IO latency in bus cycles"), INIT_PARAM(intr_delay, "Interrupt Delay in microseconds"), INIT_PARAM(rx_delay, "Receive Delay"), @@ -3062,22 +2878,16 @@ CREATE_SIM_OBJECT(NSGigE) NSGigE::Params *params = new NSGigE::Params; params->name = getInstanceName(); - - params->clock = clock; - - params->mmu = mmu; - params->pmem = physmem; + params->platform = platform; + params->system = system; params->configSpace = configspace; params->configData = configdata; - params->plat = platform; params->busNum = pci_bus; params->deviceNum = pci_dev; params->functionNum = pci_func; + params->pio_delay = pio_latency; - params->hier = hier; - params->pio_bus = pio_bus; - params->header_bus = dma_bus; - params->payload_bus = payload_bus; + params->clock = clock; params->dma_desc_free = dma_desc_free; params->dma_data_free = dma_data_free; params->dma_read_delay = dma_read_delay; @@ -3085,7 +2895,7 @@ CREATE_SIM_OBJECT(NSGigE) params->dma_read_factor = dma_read_factor; params->dma_write_factor = dma_write_factor; params->dma_no_allocate = dma_no_allocate; - params->pio_latency = pio_latency; + params->pio_delay = pio_latency; params->intr_delay = intr_delay; params->rx_delay = rx_delay; diff --git a/dev/ns_gige.hh b/dev/ns_gige.hh index 59c55056e..7bb422287 100644 --- a/dev/ns_gige.hh +++ b/dev/ns_gige.hh @@ -42,7 +42,6 @@ #include "dev/ns_gige_reg.h" #include "dev/pcidev.hh" #include "dev/pktfifo.hh" -#include "mem/bus/bus.hh" #include "sim/eventq.hh" // Hash filtering constants @@ -111,10 +110,7 @@ struct dp_rom { }; class NSGigEInt; -class PhysicalMemory; -class BaseInterface; -class HierParams; -class Bus; +class Packet; class PciConfigAll; /** @@ -165,10 +161,6 @@ class NSGigE : public PciDev eepromRead }; - private: - Addr addr; - static const Addr size = sizeof(dp_regs); - protected: /** device register file */ dp_regs regs; @@ -187,8 +179,8 @@ class NSGigE : public PciDev PacketFifo rxFifo; /** various helper vars */ - PacketPtr txPacket; - PacketPtr rxPacket; + EthPacketPtr txPacket; + EthPacketPtr rxPacket; uint8_t *txPacketBufPtr; uint8_t *rxPacketBufPtr; uint32_t txXferLen; @@ -258,16 +250,12 @@ class NSGigE : public PciDev int rxDmaLen; bool doRxDmaRead(); bool doRxDmaWrite(); - void rxDmaReadCopy(); - void rxDmaWriteCopy(); void *txDmaData; Addr txDmaAddr; int txDmaLen; bool doTxDmaRead(); bool doTxDmaWrite(); - void txDmaReadCopy(); - void txDmaWriteCopy(); void rxDmaReadDone(); friend class EventWrapper<NSGigE, &NSGigE::rxDmaReadDone>; @@ -331,7 +319,7 @@ class NSGigE : public PciDev * receive address filter */ bool rxFilterEnable; - bool rxFilter(const PacketPtr &packet); + bool rxFilter(const EthPacketPtr &packet); bool acceptBroadcast; bool acceptMulticast; bool acceptUnicast; @@ -339,8 +327,6 @@ class NSGigE : public PciDev bool acceptArp; bool multicastHashEnable; - PhysicalMemory *physmem; - /** * Interrupt management */ @@ -363,16 +349,10 @@ class NSGigE : public PciDev public: struct Params : public PciDev::Params { - PhysicalMemory *pmem; - HierParams *hier; - Bus *pio_bus; - Bus *header_bus; - Bus *payload_bus; Tick clock; Tick intr_delay; Tick tx_delay; Tick rx_delay; - Tick pio_latency; bool dma_desc_free; bool dma_data_free; Tick dma_read_delay; @@ -393,16 +373,15 @@ class NSGigE : public PciDev ~NSGigE(); const Params *params() const { return (const Params *)_params; } - virtual void writeConfig(int offset, int size, const uint8_t *data); - virtual void readConfig(int offset, int size, uint8_t *data); + virtual void writeConfig(int offset, const uint16_t data); - virtual Fault read(MemReqPtr &req, uint8_t *data); - virtual Fault write(MemReqPtr &req, const uint8_t *data); + virtual Tick read(Packet &pkt); + virtual Tick write(Packet &pkt); bool cpuIntrPending() const; void cpuIntrAck() { cpuIntrClear(); } - bool recvPacket(PacketPtr packet); + bool recvPacket(EthPacketPtr packet); void transferDone(); void setInterface(NSGigEInt *i) { assert(!interface); interface = i; } @@ -463,9 +442,6 @@ class NSGigE : public PciDev Stats::Formula coalescedTotal; Stats::Scalar<> postedInterrupts; Stats::Scalar<> droppedPackets; - - public: - Tick cacheAccess(MemReqPtr &req); }; /* @@ -480,7 +456,7 @@ class NSGigEInt : public EtherInt NSGigEInt(const std::string &name, NSGigE *d) : EtherInt(name), dev(d) { dev->setInterface(this); } - virtual bool recvPacket(PacketPtr pkt) { return dev->recvPacket(pkt); } + virtual bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); } virtual void sendDone() { dev->transferDone(); } }; diff --git a/dev/pciconfigall.cc b/dev/pciconfigall.cc index d55084fa5..dfb1d48f6 100644 --- a/dev/pciconfigall.cc +++ b/dev/pciconfigall.cc @@ -39,29 +39,21 @@ #include "dev/pciconfigall.hh" #include "dev/pcidev.hh" #include "dev/pcireg.h" -#include "mem/bus/bus.hh" -#include "mem/bus/pio_interface.hh" -#include "mem/bus/pio_interface_impl.hh" -#include "mem/functional/memory_control.hh" +#include "dev/platform.hh" +#include "mem/packet.hh" #include "sim/builder.hh" #include "sim/system.hh" using namespace std; -using namespace TheISA; -PciConfigAll::PciConfigAll(const string &name, - Addr a, MemoryController *mmu, - HierParams *hier, Bus *pio_bus, Tick pio_latency) - : PioDevice(name, NULL), addr(a) +PciConfigAll::PciConfigAll(Params *p) + : BasicPioDevice(p) { - mmu->add_child(this, RangeSize(addr, size)); + pioSize = 0xffffff; - if (pio_bus) { - pioInterface = newPioInterface(name + ".pio", hier, pio_bus, this, - &PciConfigAll::cacheAccess); - pioInterface->addAddrRange(RangeSize(addr, size)); - pioLatency = pio_latency * pio_bus->clockRate; - } + // Set backpointer for pci config. Really the config stuff should be able to + // automagically do this + p->platform->pciconfig = this; // Make all the pointers to devices null for(int x=0; x < MAX_PCI_DEV; x++) @@ -96,58 +88,59 @@ PciConfigAll::startup() } -Fault -PciConfigAll::read(MemReqPtr &req, uint8_t *data) +Tick +PciConfigAll::read(Packet &pkt) { + assert(pkt.result == Unknown); + assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); - Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); - - DPRINTF(PciConfigAll, "read va=%#x da=%#x size=%d\n", - req->vaddr, daddr, req->size); - + Addr daddr = pkt.addr - pioAddr; int device = (daddr >> 11) & 0x1F; int func = (daddr >> 8) & 0x7; int reg = daddr & 0xFF; - if (devices[device][func] == NULL) { - switch (req->size) { - // case sizeof(uint64_t): - // *(uint64_t*)data = 0xFFFFFFFFFFFFFFFF; - // return NoFault; - case sizeof(uint32_t): - *(uint32_t*)data = 0xFFFFFFFF; - return NoFault; - case sizeof(uint16_t): - *(uint16_t*)data = 0xFFFF; - return NoFault; - case sizeof(uint8_t): - *(uint8_t*)data = 0xFF; - return NoFault; - default: - panic("invalid access size(?) for PCI configspace!\n"); - } - } else { - switch (req->size) { - case sizeof(uint32_t): - case sizeof(uint16_t): - case sizeof(uint8_t): - devices[device][func]->readConfig(reg, req->size, data); - return NoFault; - default: - panic("invalid access size(?) for PCI configspace!\n"); - } + pkt.time += pioDelay; + pkt.allocate(); + + DPRINTF(PciConfigAll, "read va=%#x da=%#x size=%d\n", pkt.addr, daddr, + pkt.size); + + switch (pkt.size) { + case sizeof(uint32_t): + if (devices[device][func] == NULL) + pkt.set<uint32_t>(0xFFFFFFFF); + else + devices[device][func]->readConfig(reg, pkt.getPtr<uint32_t>()); + break; + case sizeof(uint16_t): + if (devices[device][func] == NULL) + pkt.set<uint16_t>(0xFFFF); + else + devices[device][func]->readConfig(reg, pkt.getPtr<uint16_t>()); + break; + case sizeof(uint8_t): + if (devices[device][func] == NULL) + pkt.set<uint8_t>(0xFF); + else + devices[device][func]->readConfig(reg, pkt.getPtr<uint8_t>()); + break; + default: + panic("invalid access size(?) for PCI configspace!\n"); } - - DPRINTFN("PCI Configspace ERROR: read daddr=%#x size=%d\n", - daddr, req->size); - - return NoFault; + pkt.result = Success; + return pioDelay; } -Fault -PciConfigAll::write(MemReqPtr &req, const uint8_t *data) +Tick +PciConfigAll::write(Packet &pkt) { - Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); + pkt.time += pioDelay; + + assert(pkt.result == Unknown); + assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); + assert(pkt.size == sizeof(uint8_t) || pkt.size == sizeof(uint16_t) || + pkt.size == sizeof(uint32_t)); + Addr daddr = pkt.addr - pioAddr; int device = (daddr >> 11) & 0x1F; int func = (daddr >> 8) & 0x7; @@ -155,17 +148,24 @@ PciConfigAll::write(MemReqPtr &req, const uint8_t *data) if (devices[device][func] == NULL) panic("Attempting to write to config space on non-existant device\n"); - else if (req->size != sizeof(uint8_t) && - req->size != sizeof(uint16_t) && - req->size != sizeof(uint32_t)) - panic("invalid access size(?) for PCI configspace!\n"); DPRINTF(PciConfigAll, "write - va=%#x size=%d data=%#x\n", - req->vaddr, req->size, *(uint32_t*)data); - - devices[device][func]->writeConfig(reg, req->size, data); - - return NoFault; + pkt.addr, pkt.size, pkt.get<uint32_t>()); + + switch (pkt.size) { + case sizeof(uint8_t): + devices[device][func]->writeConfig(reg, pkt.get<uint8_t>()); + break; + case sizeof(uint16_t): + devices[device][func]->writeConfig(reg, pkt.get<uint16_t>()); + break; + case sizeof(uint32_t): + devices[device][func]->writeConfig(reg, pkt.get<uint32_t>()); + break; + default: + panic("invalid pci config write size\n"); + } + return pioDelay; } void @@ -188,40 +188,34 @@ PciConfigAll::unserialize(Checkpoint *cp, const std::string §ion) */ } -Tick -PciConfigAll::cacheAccess(MemReqPtr &req) -{ - return curTick + pioLatency; -} - #ifndef DOXYGEN_SHOULD_SKIP_THIS BEGIN_DECLARE_SIM_OBJECT_PARAMS(PciConfigAll) - SimObjectParam<MemoryController *> mmu; - Param<Addr> addr; - Param<Addr> mask; - SimObjectParam<Bus*> pio_bus; + Param<Addr> pio_addr; Param<Tick> pio_latency; - SimObjectParam<HierParams *> hier; + SimObjectParam<Platform *> platform; + SimObjectParam<System *> system; END_DECLARE_SIM_OBJECT_PARAMS(PciConfigAll) BEGIN_INIT_SIM_OBJECT_PARAMS(PciConfigAll) - INIT_PARAM(mmu, "Memory Controller"), - INIT_PARAM(addr, "Device Address"), - INIT_PARAM(mask, "Address Mask"), - INIT_PARAM_DFLT(pio_bus, "The IO Bus to attach to", NULL), - INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1), - INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) + INIT_PARAM(pio_addr, "Device Address"), + INIT_PARAM(pio_latency, "Programmed IO latency"), + INIT_PARAM(platform, "platform"), + INIT_PARAM(system, "system object") END_INIT_SIM_OBJECT_PARAMS(PciConfigAll) CREATE_SIM_OBJECT(PciConfigAll) { - return new PciConfigAll(getInstanceName(), addr, mmu, hier, pio_bus, - pio_latency); + BasicPioDevice::Params *p = new BasicPioDevice::Params; + p->pio_addr = pio_addr; + p->pio_delay = pio_latency; + p->platform = platform; + p->system = system; + return new PciConfigAll(p); } REGISTER_SIM_OBJECT("PciConfigAll", PciConfigAll) diff --git a/dev/pciconfigall.hh b/dev/pciconfigall.hh index c6a0241d8..2393b445e 100644 --- a/dev/pciconfigall.hh +++ b/dev/pciconfigall.hh @@ -43,7 +43,6 @@ static const uint32_t MAX_PCI_DEV = 32; static const uint32_t MAX_PCI_FUNC = 8; class PciDev; -class MemoryController; /** * PCI Config Space @@ -52,12 +51,9 @@ class MemoryController; * space and passes the requests on to TsunamiPCIDev devices as * appropriate. */ -class PciConfigAll : public PioDevice +class PciConfigAll : public BasicPioDevice { private: - Addr addr; - static const Addr size = 0xffffff; - /** * Pointers to all the devices that are registered with this * particular config space. @@ -67,15 +63,9 @@ class PciConfigAll : public PioDevice public: /** * Constructor for PCIConfigAll - * @param name name of the object - * @param a base address of the write - * @param mmu the memory controller - * @param hier object to store parameters universal the device hierarchy - * @param bus The bus that this device is attached to + * @param p parameters structure */ - PciConfigAll(const std::string &name, Addr a, MemoryController *mmu, - HierParams *hier, Bus *pio_bus, Tick pio_latency); - + PciConfigAll(Params *p); /** * Check if a device exists. @@ -99,11 +89,10 @@ class PciConfigAll : public PioDevice * Read something in PCI config space. If the device does not exist * -1 is returned, if the device does exist its PciDev::ReadConfig (or the * virtual function that overrides) it is called. - * @param req Contains the address of the field to read. - * @param data Return the field read. - * @return The fault condition of the access. + * @param pkt Contains the address of the field to read. + * @return Amount of time to do the read */ - virtual Fault read(MemReqPtr &req, uint8_t *data); + virtual Tick read(Packet &pkt); /** * Write to PCI config spcae. If the device does not exit the simulator @@ -114,7 +103,7 @@ class PciConfigAll : public PioDevice * @return The fault condition of the access. */ - virtual Fault write(MemReqPtr &req, const uint8_t *data); + virtual Tick write(Packet &pkt); /** * Start up function to check if more than one person is using an interrupt line @@ -134,14 +123,6 @@ class PciConfigAll : public PioDevice * @param section The section name of this object */ virtual void unserialize(Checkpoint *cp, const std::string §ion); - - /** - * Return how long this access will take. - * @param req the memory request to calcuate - * @return Tick when the request is done - */ - Tick cacheAccess(MemReqPtr &req); - }; #endif // __PCICONFIGALL_HH__ diff --git a/dev/pcidev.cc b/dev/pcidev.cc index a05ee3803..c40ef62e4 100644 --- a/dev/pcidev.cc +++ b/dev/pcidev.cc @@ -39,20 +39,20 @@ #include "base/misc.hh" #include "base/str.hh" // for to_number #include "base/trace.hh" -#include "dev/pcidev.hh" #include "dev/pciconfigall.hh" -#include "mem/bus/bus.hh" -#include "mem/functional/memory_control.hh" +#include "dev/pcidev.hh" +#include "dev/tsunamireg.h" +#include "mem/packet.hh" #include "sim/builder.hh" +#include "sim/byteswap.hh" #include "sim/param.hh" #include "sim/root.hh" -#include "dev/tsunamireg.h" using namespace std; PciDev::PciDev(Params *p) - : DmaDevice(p->name, p->plat), _params(p), plat(p->plat), - configData(p->configData) + : DmaDevice(p), plat(p->platform), configData(p->configData), + pioDelay(p->pio_delay) { // copy the config data from the PciConfigData object if (configData) { @@ -70,214 +70,180 @@ PciDev::PciDev(Params *p) p->configSpace->registerDevice(p->deviceNum, p->functionNum, this); } -Fault -PciDev::read(MemReqPtr &req, uint8_t *data) -{ return NoFault; } - -Fault -PciDev::write(MemReqPtr &req, const uint8_t *data) -{ return NoFault; } - -Fault -PciDev::readBar0(MemReqPtr &req, Addr daddr, uint8_t *data) -{ panic("not implemented"); } - -Fault -PciDev::readBar1(MemReqPtr &req, Addr daddr, uint8_t *data) -{ panic("not implemented"); } +void +PciDev::readConfig(int offset, uint8_t *data) +{ + if (offset >= PCI_DEVICE_SPECIFIC) + panic("Device specific PCI config space not implemented!\n"); -Fault -PciDev::readBar2(MemReqPtr &req, Addr daddr, uint8_t *data) -{ panic("not implemented"); } + *data = config.data[offset]; -Fault -PciDev::readBar3(MemReqPtr &req, Addr daddr, uint8_t *data) -{ panic("not implemented"); } + DPRINTF(PCIDEV, + "read device: %#x function: %#x register: %#x 1 bytes: data: %#x\n", + params()->deviceNum, params()->functionNum, offset, *data); +} -Fault -PciDev::readBar4(MemReqPtr &req, Addr daddr, uint8_t *data) -{ panic("not implemented"); } +void +PciDev::addressRanges(AddrRangeList &range_list) +{ + int x = 0; + range_list.clear(); + for (x = 0; x < 6; x++) + if (BARAddrs[x] != 0) + range_list.push_back(RangeSize(BARAddrs[x],BARSize[x])); +} -Fault -PciDev::readBar5(MemReqPtr &req, Addr daddr, uint8_t *data) -{ panic("not implemented"); } +void +PciDev::readConfig(int offset, uint16_t *data) +{ + if (offset >= PCI_DEVICE_SPECIFIC) + panic("Device specific PCI config space not implemented!\n"); -Fault -PciDev::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data) -{ panic("not implemented"); } + *data = *(uint16_t*)&config.data[offset]; -Fault -PciDev::writeBar1(MemReqPtr &req, Addr daddr, const uint8_t *data) -{ panic("not implemented"); } + DPRINTF(PCIDEV, + "read device: %#x function: %#x register: %#x 2 bytes: data: %#x\n", + params()->deviceNum, params()->functionNum, offset, *data); +} -Fault -PciDev::writeBar2(MemReqPtr &req, Addr daddr, const uint8_t *data) -{ panic("not implemented"); } +void +PciDev::readConfig(int offset, uint32_t *data) +{ + if (offset >= PCI_DEVICE_SPECIFIC) + panic("Device specific PCI config space not implemented!\n"); -Fault -PciDev::writeBar3(MemReqPtr &req, Addr daddr, const uint8_t *data) -{ panic("not implemented"); } + *data = *(uint32_t*)&config.data[offset]; -Fault -PciDev::writeBar4(MemReqPtr &req, Addr daddr, const uint8_t *data) -{ panic("not implemented"); } + DPRINTF(PCIDEV, + "read device: %#x function: %#x register: %#x 4 bytes: data: %#x\n", + params()->deviceNum, params()->functionNum, offset, *data); +} -Fault -PciDev::writeBar5(MemReqPtr &req, Addr daddr, const uint8_t *data) -{ panic("not implemented"); } void -PciDev::readConfig(int offset, int size, uint8_t *data) +PciDev::writeConfig(int offset, const uint8_t data) { if (offset >= PCI_DEVICE_SPECIFIC) panic("Device specific PCI config space not implemented!\n"); - switch(size) { - case sizeof(uint8_t): - *data = config.data[offset]; - break; - case sizeof(uint16_t): - *(uint16_t*)data = *(uint16_t*)&config.data[offset]; + DPRINTF(PCIDEV, + "write device: %#x function: %#x reg: %#x size: 1 data: %#x\n", + params()->deviceNum, params()->functionNum, offset, data); + + switch (offset) { + case PCI0_INTERRUPT_LINE: + config.interruptLine = data; + case PCI_CACHE_LINE_SIZE: + config.cacheLineSize = data; + case PCI_LATENCY_TIMER: + config.latencyTimer = data; break; - case sizeof(uint32_t): - *(uint32_t*)data = *(uint32_t*)&config.data[offset]; + /* Do nothing for these read-only registers */ + case PCI0_INTERRUPT_PIN: + case PCI0_MINIMUM_GRANT: + case PCI0_MAXIMUM_LATENCY: + case PCI_CLASS_CODE: + case PCI_REVISION_ID: break; default: - panic("Invalid PCI configuration read size!\n"); + panic("writing to a read only register"); } - - DPRINTF(PCIDEV, - "read device: %#x function: %#x register: %#x %d bytes: data: %#x\n", - params()->deviceNum, params()->functionNum, offset, size, - *(uint32_t*)data); } void -PciDev::writeConfig(int offset, int size, const uint8_t *data) +PciDev::writeConfig(int offset, const uint16_t data) { if (offset >= PCI_DEVICE_SPECIFIC) panic("Device specific PCI config space not implemented!\n"); - uint8_t &data8 = *(uint8_t*)data; - uint16_t &data16 = *(uint16_t*)data; - uint32_t &data32 = *(uint32_t*)data; - DPRINTF(PCIDEV, - "write device: %#x function: %#x reg: %#x size: %d data: %#x\n", - params()->deviceNum, params()->functionNum, offset, size, data32); - - switch (size) { - case sizeof(uint8_t): // 1-byte access - switch (offset) { - case PCI0_INTERRUPT_LINE: - config.interruptLine = data8; - case PCI_CACHE_LINE_SIZE: - config.cacheLineSize = data8; - case PCI_LATENCY_TIMER: - config.latencyTimer = data8; - break; - /* Do nothing for these read-only registers */ - case PCI0_INTERRUPT_PIN: - case PCI0_MINIMUM_GRANT: - case PCI0_MAXIMUM_LATENCY: - case PCI_CLASS_CODE: - case PCI_REVISION_ID: - break; - default: - panic("writing to a read only register"); - } + "write device: %#x function: %#x reg: %#x size: 2 data: %#x\n", + params()->deviceNum, params()->functionNum, offset, data); + + switch (offset) { + case PCI_COMMAND: + config.command = data; + case PCI_STATUS: + config.status = data; + case PCI_CACHE_LINE_SIZE: + config.cacheLineSize = data; break; + default: + panic("writing to a read only register"); + } +} - case sizeof(uint16_t): // 2-byte access - switch (offset) { - case PCI_COMMAND: - config.command = data16; - case PCI_STATUS: - config.status = data16; - case PCI_CACHE_LINE_SIZE: - config.cacheLineSize = data16; - break; - default: - panic("writing to a read only register"); - } - break; - case sizeof(uint32_t): // 4-byte access - switch (offset) { - case PCI0_BASE_ADDR0: - case PCI0_BASE_ADDR1: - case PCI0_BASE_ADDR2: - case PCI0_BASE_ADDR3: - case PCI0_BASE_ADDR4: - case PCI0_BASE_ADDR5: - - uint32_t barnum, bar_mask; - Addr base_addr, base_size, space_base; - - barnum = BAR_NUMBER(offset); - - if (BAR_IO_SPACE(letoh(config.baseAddr[barnum]))) { - bar_mask = BAR_IO_MASK; - space_base = TSUNAMI_PCI0_IO; - } else { - bar_mask = BAR_MEM_MASK; - space_base = TSUNAMI_PCI0_MEMORY; - } +void +PciDev::writeConfig(int offset, const uint32_t data) +{ + if (offset >= PCI_DEVICE_SPECIFIC) + panic("Device specific PCI config space not implemented!\n"); - // Writing 0xffffffff to a BAR tells the card to set the - // value of the bar to size of memory it needs - if (letoh(data32) == 0xffffffff) { - // This is I/O Space, bottom two bits are read only + DPRINTF(PCIDEV, + "write device: %#x function: %#x reg: %#x size: 4 data: %#x\n", + params()->deviceNum, params()->functionNum, offset, data); + + switch (offset) { + case PCI0_BASE_ADDR0: + case PCI0_BASE_ADDR1: + case PCI0_BASE_ADDR2: + case PCI0_BASE_ADDR3: + case PCI0_BASE_ADDR4: + case PCI0_BASE_ADDR5: + + uint32_t barnum, bar_mask; + Addr base_addr, base_size, space_base; + + barnum = BAR_NUMBER(offset); + + if (BAR_IO_SPACE(letoh(config.baseAddr[barnum]))) { + bar_mask = BAR_IO_MASK; + space_base = TSUNAMI_PCI0_IO; + } else { + bar_mask = BAR_MEM_MASK; + space_base = TSUNAMI_PCI0_MEMORY; + } - config.baseAddr[barnum] = letoh( - (~(BARSize[barnum] - 1) & ~bar_mask) | - (letoh(config.baseAddr[barnum]) & bar_mask)); - } else { - MemoryController *mmu = params()->mmu; + // Writing 0xffffffff to a BAR tells the card to set the + // value of the bar to size of memory it needs + if (letoh(data) == 0xffffffff) { + // This is I/O Space, bottom two bits are read only - config.baseAddr[barnum] = letoh( - (letoh(data32) & ~bar_mask) | + config.baseAddr[barnum] = letoh( + (~(BARSize[barnum] - 1) & ~bar_mask) | (letoh(config.baseAddr[barnum]) & bar_mask)); + } else { + config.baseAddr[barnum] = letoh( + (letoh(data) & ~bar_mask) | + (letoh(config.baseAddr[barnum]) & bar_mask)); + + if (letoh(config.baseAddr[barnum]) & ~bar_mask) { + base_addr = (letoh(data) & ~bar_mask) + space_base; + base_size = BARSize[barnum]; + BARAddrs[barnum] = base_addr; - if (letoh(config.baseAddr[barnum]) & ~bar_mask) { - base_addr = (letoh(data32) & ~bar_mask) + space_base; - base_size = BARSize[barnum]; - - // It's never been set - if (BARAddrs[barnum] == 0) - mmu->add_child((FunctionalMemory *)this, - RangeSize(base_addr, base_size)); - else - mmu->update_child((FunctionalMemory *)this, - RangeSize(BARAddrs[barnum], base_size), - RangeSize(base_addr, base_size)); - - BARAddrs[barnum] = base_addr; - } + pioPort->sendStatusChange(Port::RangeChange); } - break; - - case PCI0_ROM_BASE_ADDR: - if (letoh(data32) == 0xfffffffe) - config.expansionROM = htole((uint32_t)0xffffffff); - else - config.expansionROM = data32; - break; - - case PCI_COMMAND: - // This could also clear some of the error bits in the Status - // register. However they should never get set, so lets ignore - // it for now - config.command = data16; - break; - - default: - DPRINTF(PCIDEV, "Writing to a read only register"); } break; + case PCI0_ROM_BASE_ADDR: + if (letoh(data) == 0xfffffffe) + config.expansionROM = htole((uint32_t)0xffffffff); + else + config.expansionROM = data; + break; + + case PCI_COMMAND: + // This could also clear some of the error bits in the Status + // register. However they should never get set, so lets ignore + // it for now + config.command = data; + break; + default: - panic("invalid access size"); + DPRINTF(PCIDEV, "Writing to a read only register"); } } @@ -296,12 +262,6 @@ PciDev::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_ARRAY(BARAddrs, sizeof(BARAddrs) / sizeof(BARAddrs[0])); UNSERIALIZE_ARRAY(config.data, sizeof(config.data) / sizeof(config.data[0])); - - // Add the MMU mappings for the BARs - for (int i=0; i < 6; i++) { - if (BARAddrs[i] != 0) - params()->mmu->add_child(this, RangeSize(BARAddrs[i], BARSize[i])); - } } #ifndef DOXYGEN_SHOULD_SKIP_THIS diff --git a/dev/pcidev.hh b/dev/pcidev.hh index bdfc6b932..fc4773908 100644 --- a/dev/pcidev.hh +++ b/dev/pcidev.hh @@ -44,7 +44,6 @@ #define BAR_NUMBER(x) (((x) - PCI0_BASE_ADDR0) >> 0x2); class PciConfigAll; -class MemoryController; /** @@ -85,12 +84,8 @@ class PciConfigData : public SimObject class PciDev : public DmaDevice { public: - struct Params + struct Params : public ::PioDevice::Params { - std::string name; - Platform *plat; - MemoryController *mmu; - /** * A pointer to the configspace all object that calls us when * a read comes to this particular device/function. @@ -111,13 +106,13 @@ class PciDev : public DmaDevice /** The function number */ uint32_t functionNum; - }; - protected: - Params *_params; + /** The latency for pio accesses. */ + Tick pio_delay; + }; public: - const Params *params() const { return _params; } + const Params *params() const { return (const Params *)_params; } protected: /** The current config space. Unlike the PciConfigData this is @@ -164,6 +159,7 @@ class PciDev : public DmaDevice protected: Platform *plat; PciConfigData *configData; + Tick pioDelay; public: Addr pciToDma(Addr pciAddr) const @@ -181,7 +177,11 @@ class PciDev : public DmaDevice interruptLine() { return configData->config.interruptLine; } - public: + /** return the address ranges that this device responds to. + * @params range_list range list to populate with ranges + */ + void addressRanges(AddrRangeList &range_list); + /** * Constructor for PCI Dev. This function copies data from the * config file object PCIConfigData and registers the device with @@ -189,39 +189,6 @@ class PciDev : public DmaDevice */ PciDev(Params *params); - virtual Fault read(MemReqPtr &req, uint8_t *data); - virtual Fault write(MemReqPtr &req, const uint8_t *data); - - public: - /** - * Implement the read/write as BAR accesses - */ - Fault readBar(MemReqPtr &req, uint8_t *data); - Fault writeBar(MemReqPtr &req, const uint8_t *data); - - public: - /** - * Read from a specific BAR - */ - virtual Fault readBar0(MemReqPtr &req, Addr daddr, uint8_t *data); - virtual Fault readBar1(MemReqPtr &req, Addr daddr, uint8_t *data); - virtual Fault readBar2(MemReqPtr &req, Addr daddr, uint8_t *data); - virtual Fault readBar3(MemReqPtr &req, Addr daddr, uint8_t *data); - virtual Fault readBar4(MemReqPtr &req, Addr daddr, uint8_t *data); - virtual Fault readBar5(MemReqPtr &req, Addr daddr, uint8_t *data); - - public: - /** - * Write to a specific BAR - */ - virtual Fault writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data); - virtual Fault writeBar1(MemReqPtr &req, Addr daddr, const uint8_t *data); - virtual Fault writeBar2(MemReqPtr &req, Addr daddr, const uint8_t *data); - virtual Fault writeBar3(MemReqPtr &req, Addr daddr, const uint8_t *data); - virtual Fault writeBar4(MemReqPtr &req, Addr daddr, const uint8_t *data); - virtual Fault writeBar5(MemReqPtr &req, Addr daddr, const uint8_t *data); - - public: /** * Write to the PCI config space data that is stored locally. This may be * overridden by the device but at some point it will eventually call this @@ -230,7 +197,9 @@ class PciDev : public DmaDevice * @param size the size of the write * @param data the data to write */ - virtual void writeConfig(int offset, int size, const uint8_t* data); + virtual void writeConfig(int offset, const uint8_t data); + virtual void writeConfig(int offset, const uint16_t data); + virtual void writeConfig(int offset, const uint32_t data); /** @@ -241,7 +210,9 @@ class PciDev : public DmaDevice * @param size the size of the read * @param data pointer to the location where the read value should be stored */ - virtual void readConfig(int offset, int size, uint8_t *data); + virtual void readConfig(int offset, uint8_t *data); + virtual void readConfig(int offset, uint16_t *data); + virtual void readConfig(int offset, uint32_t *data); /** * Serialize this object to the given output stream. @@ -256,43 +227,4 @@ class PciDev : public DmaDevice */ virtual void unserialize(Checkpoint *cp, const std::string §ion); }; - -inline Fault -PciDev::readBar(MemReqPtr &req, uint8_t *data) -{ - using namespace TheISA; - if (isBAR(req->paddr, 0)) - return readBar0(req, req->paddr - BARAddrs[0], data); - if (isBAR(req->paddr, 1)) - return readBar1(req, req->paddr - BARAddrs[1], data); - if (isBAR(req->paddr, 2)) - return readBar2(req, req->paddr - BARAddrs[2], data); - if (isBAR(req->paddr, 3)) - return readBar3(req, req->paddr - BARAddrs[3], data); - if (isBAR(req->paddr, 4)) - return readBar4(req, req->paddr - BARAddrs[4], data); - if (isBAR(req->paddr, 5)) - return readBar5(req, req->paddr - BARAddrs[5], data); - return genMachineCheckFault(); -} - -inline Fault -PciDev::writeBar(MemReqPtr &req, const uint8_t *data) -{ - using namespace TheISA; - if (isBAR(req->paddr, 0)) - return writeBar0(req, req->paddr - BARAddrs[0], data); - if (isBAR(req->paddr, 1)) - return writeBar1(req, req->paddr - BARAddrs[1], data); - if (isBAR(req->paddr, 2)) - return writeBar2(req, req->paddr - BARAddrs[2], data); - if (isBAR(req->paddr, 3)) - return writeBar3(req, req->paddr - BARAddrs[3], data); - if (isBAR(req->paddr, 4)) - return writeBar4(req, req->paddr - BARAddrs[4], data); - if (isBAR(req->paddr, 5)) - return writeBar5(req, req->paddr - BARAddrs[5], data); - return genMachineCheckFault(); -} - #endif // __DEV_PCIDEV_HH__ diff --git a/dev/pktfifo.cc b/dev/pktfifo.cc index 639009be9..922a66912 100644 --- a/dev/pktfifo.cc +++ b/dev/pktfifo.cc @@ -38,8 +38,8 @@ PacketFifo::copyout(void *dest, int offset, int len) if (offset + len >= size()) return false; - list<PacketPtr>::iterator p = fifo.begin(); - list<PacketPtr>::iterator end = fifo.end(); + list<EthPacketPtr>::iterator p = fifo.begin(); + list<EthPacketPtr>::iterator end = fifo.end(); while (len > 0) { while (offset >= (*p)->length) { offset -= (*p)->length; @@ -70,8 +70,8 @@ PacketFifo::serialize(const string &base, ostream &os) paramOut(os, base + ".packets", fifo.size()); int i = 0; - list<PacketPtr>::iterator p = fifo.begin(); - list<PacketPtr>::iterator end = fifo.end(); + list<EthPacketPtr>::iterator p = fifo.begin(); + list<EthPacketPtr>::iterator end = fifo.end(); while (p != end) { (*p)->serialize(csprintf("%s.packet%d", base, i), os); ++p; @@ -92,7 +92,7 @@ PacketFifo::unserialize(const string &base, Checkpoint *cp, fifo.clear(); for (int i = 0; i < fifosize; ++i) { - PacketPtr p = new PacketData(16384); + EthPacketPtr p = new EthPacketData(16384); p->unserialize(csprintf("%s.packet%d", base, i), cp, section); fifo.push_back(p); } diff --git a/dev/pktfifo.hh b/dev/pktfifo.hh index e245840a8..336da22d8 100644 --- a/dev/pktfifo.hh +++ b/dev/pktfifo.hh @@ -40,11 +40,11 @@ class Checkpoint; class PacketFifo { public: - typedef std::list<PacketPtr> fifo_list; + typedef std::list<EthPacketPtr> fifo_list; typedef fifo_list::iterator iterator; protected: - std::list<PacketPtr> fifo; + std::list<EthPacketPtr> fifo; int _maxsize; int _size; int _reserved; @@ -71,9 +71,9 @@ class PacketFifo iterator begin() { return fifo.begin(); } iterator end() { return fifo.end(); } - PacketPtr front() { return fifo.front(); } + EthPacketPtr front() { return fifo.front(); } - bool push(PacketPtr ptr) + bool push(EthPacketPtr ptr) { assert(ptr->length); assert(_reserved <= ptr->length); @@ -92,7 +92,7 @@ class PacketFifo if (empty()) return; - PacketPtr &packet = fifo.front(); + EthPacketPtr &packet = fifo.front(); _size -= packet->length; _size -= packet->slack; packet->slack = 0; @@ -111,7 +111,7 @@ class PacketFifo void remove(iterator i) { - PacketPtr &packet = *i; + EthPacketPtr &packet = *i; if (i != fifo.begin()) { iterator prev = i; --prev; diff --git a/dev/platform.cc b/dev/platform.cc index 5b667b12c..9d10e0828 100644 --- a/dev/platform.cc +++ b/dev/platform.cc @@ -33,8 +33,8 @@ using namespace std; using namespace TheISA; -Platform::Platform(const string &name, IntrControl *intctrl, PciConfigAll *pci) - : SimObject(name), intrctrl(intctrl), pciconfig(pci) +Platform::Platform(const string &name, IntrControl *intctrl) + : SimObject(name), intrctrl(intctrl) { } diff --git a/dev/platform.hh b/dev/platform.hh index 1ee645454..f149ca2fb 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,9 +55,13 @@ 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); + Platform(const std::string &name, IntrControl *intctrl); virtual ~Platform(); + virtual void init() { if (pciconfig == NULL) panic("PCI Config not set"); } virtual void postConsoleInt() = 0; virtual void clearConsoleInt() = 0; virtual Tick intrFrequency() = 0; diff --git a/dev/simconsole.cc b/dev/simconsole.cc index b818e61f4..c3e4f554a 100644 --- a/dev/simconsole.cc +++ b/dev/simconsole.cc @@ -49,7 +49,6 @@ #include "dev/platform.hh" #include "dev/simconsole.hh" #include "dev/uart.hh" -#include "mem/functional/memory_control.hh" #include "sim/builder.hh" using namespace std; diff --git a/dev/simple_disk.cc b/dev/simple_disk.cc index b8c5d44ab..9eee4668c 100644 --- a/dev/simple_disk.cc +++ b/dev/simple_disk.cc @@ -42,14 +42,14 @@ #include "base/trace.hh" #include "dev/disk_image.hh" #include "dev/simple_disk.hh" -#include "mem/functional/physical.hh" +#include "mem/port.hh" #include "sim/builder.hh" +#include "sim/system.hh" using namespace std; -SimpleDisk::SimpleDisk(const string &name, PhysicalMemory *pmem, - DiskImage *img) - : SimObject(name), physmem(pmem), image(img) +SimpleDisk::SimpleDisk(const string &name, System *sys, DiskImage *img) + : SimObject(name), system(sys), image(img) {} SimpleDisk::~SimpleDisk() @@ -59,9 +59,7 @@ SimpleDisk::~SimpleDisk() void SimpleDisk::read(Addr addr, baddr_t block, int count) const { - uint8_t *data = physmem->dma_addr(addr, count); - if (!data) - panic("dma out of range! read addr=%#x count=%d\n", addr, count); + uint8_t *data = new uint8_t[SectorSize * count]; if (count & (SectorSize - 1)) panic("Not reading a multiple of a sector (count = %d)", count); @@ -69,8 +67,12 @@ SimpleDisk::read(Addr addr, baddr_t block, int count) const for (int i = 0, j = 0; i < count; i += SectorSize, j++) image->read(data + i, block + j); + system->functionalPort.writeBlob(addr, data, count); + DPRINTF(SimpleDisk, "read block=%#x len=%d\n", (uint64_t)block, count); DDUMP(SimpleDiskData, data, count); + + delete data; } void @@ -89,21 +91,21 @@ SimpleDisk::write(Addr addr, baddr_t block, int count) BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleDisk) - SimObjectParam<PhysicalMemory *> physmem; + SimObjectParam<System *> system; SimObjectParam<DiskImage *> disk; END_DECLARE_SIM_OBJECT_PARAMS(SimpleDisk) BEGIN_INIT_SIM_OBJECT_PARAMS(SimpleDisk) - INIT_PARAM(physmem, "Physical Memory"), + INIT_PARAM(system, "System pointer"), INIT_PARAM(disk, "Disk Image") END_INIT_SIM_OBJECT_PARAMS(SimpleDisk) CREATE_SIM_OBJECT(SimpleDisk) { - return new SimpleDisk(getInstanceName(), physmem, disk); + return new SimpleDisk(getInstanceName(), system, disk); } REGISTER_SIM_OBJECT("SimpleDisk", SimpleDisk) diff --git a/dev/simple_disk.hh b/dev/simple_disk.hh index 57f81c5a9..19967f208 100644 --- a/dev/simple_disk.hh +++ b/dev/simple_disk.hh @@ -37,7 +37,7 @@ #include "arch/isa_traits.hh" class DiskImage; -class PhysicalMemory; +class System; /* * Trivial interface to a disk image used by the System Console @@ -48,11 +48,11 @@ class SimpleDisk : public SimObject typedef uint64_t baddr_t; protected: - PhysicalMemory *physmem; + System *system; DiskImage *image; public: - SimpleDisk(const std::string &name, PhysicalMemory *pmem, DiskImage *img); + SimpleDisk(const std::string &name, System *sys, DiskImage *img); ~SimpleDisk(); void read(Addr addr, baddr_t block, int count) const; diff --git a/dev/sinic.cc b/dev/sinic.cc index 0853717ba..66ca88dbe 100644 --- a/dev/sinic.cc +++ b/dev/sinic.cc @@ -28,6 +28,7 @@ #include <cstdio> #include <deque> +#include <limits> #include <string> #include "base/inet.hh" @@ -36,12 +37,7 @@ #include "dev/etherlink.hh" #include "dev/sinic.hh" #include "dev/pciconfigall.hh" -#include "mem/bus/bus.hh" -#include "mem/bus/dma_interface.hh" -#include "mem/bus/pio_interface.hh" -#include "mem/bus/pio_interface_impl.hh" -#include "mem/functional/memory_control.hh" -#include "mem/functional/physical.hh" +#include "mem/packet.hh" #include "sim/builder.hh" #include "sim/debug.hh" #include "sim/eventq.hh" @@ -87,7 +83,6 @@ Base::Base(Params *p) Device::Device(Params *p) : Base(p), plat(p->plat), physmem(p->physmem), rxUnique(0), txUnique(0), virtualRegs(p->virtual_count < 1 ? 1 : p->virtual_count), - rxFifo(p->rx_fifo_size), txFifo(p->tx_fifo_size), rxKickTick(0), txKickTick(0), txEvent(this), rxDmaEvent(this), txDmaEvent(this), dmaReadDelay(p->dma_read_delay), dmaReadFactor(p->dma_read_factor), @@ -95,25 +90,6 @@ Device::Device(Params *p) { reset(); - if (p->pio_bus) { - pioInterface = newPioInterface(p->name + ".pio", p->hier, p->pio_bus, - this, &Device::cacheAccess); - pioLatency = p->pio_latency * p->pio_bus->clockRate; - } - - if (p->header_bus) { - if (p->payload_bus) - dmaInterface = new DMAInterface<Bus>(p->name + ".dma", - p->header_bus, - p->payload_bus, 1, - p->dma_no_allocate); - else - dmaInterface = new DMAInterface<Bus>(p->name + ".dma", - p->header_bus, - p->header_bus, 1, - p->dma_no_allocate); - } else if (p->payload_bus) - panic("must define a header bus if defining a payload bus"); } Device::~Device() @@ -289,29 +265,6 @@ Device::regStats() rxPacketRate = rxPackets / simSeconds; } -/** - * This is to write to the PCI general configuration registers - */ -void -Device::writeConfig(int offset, int size, const uint8_t *data) -{ - switch (offset) { - case PCI0_BASE_ADDR0: - // Need to catch writes to BARs to update the PIO interface - PciDev::writeConfig(offset, size, data); - if (BARAddrs[0] != 0) { - if (pioInterface) - pioInterface->addAddrRange(RangeSize(BARAddrs[0], BARSize[0])); - - BARAddrs[0] &= EV5::PAddrUncachedMask; - } - break; - - default: - PciDev::writeConfig(offset, size, data); - } -} - void Device::prepareIO(int cpu, int index) { @@ -358,76 +311,65 @@ Device::prepareWrite(int cpu, int index) /** * I/O read of device register */ -Fault -Device::read(MemReqPtr &req, uint8_t *data) +Tick +Device::read(Packet &pkt) { assert(config.command & PCI_CMD_MSE); - Fault fault = readBar(req, data); - - if (fault && fault->isMachineCheckFault()) { - panic("address does not map to a BAR pa=%#x va=%#x size=%d", - req->paddr, req->vaddr, req->size); - - return genMachineCheckFault(); - } + assert(pkt.addr >= BARAddrs[0] && pkt.size < BARSize[0]); - return fault; -} - -Fault -Device::readBar0(MemReqPtr &req, Addr daddr, uint8_t *data) -{ - int cpu = (req->xc->readMiscReg(TheISA::IPR_PALtemp16) >> 8) & 0xff; + int cpu = pkt.req->getCpuNum(); + Addr daddr = pkt.addr - BARAddrs[0]; Addr index = daddr >> Regs::VirtualShift; Addr raddr = daddr & Regs::VirtualMask; + pkt.time += pioDelay; + pkt.allocate(); + if (!regValid(raddr)) - panic("invalid register: cpu=%d vnic=%d da=%#x pa=%#x va=%#x size=%d", - cpu, index, daddr, req->paddr, req->vaddr, req->size); + panic("invalid register: cpu=%d vnic=%d da=%#x pa=%#x size=%d", + cpu, index, daddr, pkt.addr, pkt.size); const Regs::Info &info = regInfo(raddr); if (!info.read) panic("read %s (write only): " - "cpu=%d vnic=%d da=%#x pa=%#x va=%#x size=%d", - info.name, cpu, index, daddr, req->paddr, req->vaddr, req->size); + "cpu=%d vnic=%d da=%#x pa=%#x size=%d", + info.name, cpu, index, daddr, pkt.addr, pkt.size); - if (req->size != info.size) panic("read %s (invalid size): " - "cpu=%d vnic=%d da=%#x pa=%#x va=%#x size=%d", - info.name, cpu, index, daddr, req->paddr, req->vaddr, req->size); + "cpu=%d vnic=%d da=%#x pa=%#x size=%d", + info.name, cpu, index, daddr, pkt.addr, pkt.size); prepareRead(cpu, index); uint64_t value = 0; - if (req->size == 4) { - uint32_t ® = *(uint32_t *)data; - reg = regData32(raddr); + if (pkt.size == 4) { + uint32_t reg = regData32(raddr); + pkt.set(reg); value = reg; } - if (req->size == 8) { - uint64_t ® = *(uint64_t *)data; - reg = regData64(raddr); + if (pkt.size == 8) { + uint64_t reg = regData64(raddr); + pkt.set(reg); value = reg; } DPRINTF(EthernetPIO, - "read %s: cpu=%d vnic=%d da=%#x pa=%#x va=%#x size=%d val=%#x\n", - info.name, cpu, index, daddr, req->paddr, req->vaddr, req->size, - value); + "read %s: cpu=%d vnic=%d da=%#x pa=%#x size=%d val=%#x\n", + info.name, cpu, index, daddr, pkt.addr, pkt.size, value); // reading the interrupt status register has the side effect of // clearing it if (raddr == Regs::IntrStatus) devIntrClear(); - return NoFault; + return pioDelay; } /** * IPR read of device register - */ -Fault + + Fault Device::iprRead(Addr daddr, int cpu, uint64_t &result) { if (!regValid(daddr)) @@ -453,74 +395,62 @@ Device::iprRead(Addr daddr, int cpu, uint64_t &result) return NoFault; } - +*/ /** * I/O write of device register */ -Fault -Device::write(MemReqPtr &req, const uint8_t *data) +Tick +Device::write(Packet &pkt) { assert(config.command & PCI_CMD_MSE); - Fault fault = writeBar(req, data); - - if (fault && fault->isMachineCheckFault()) { - panic("address does not map to a BAR pa=%#x va=%#x size=%d", - req->paddr, req->vaddr, req->size); + assert(pkt.addr >= BARAddrs[0] && pkt.size < BARSize[0]); - return genMachineCheckFault(); - } - - return fault; -} - -Fault -Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data) -{ - int cpu = (req->xc->readMiscReg(TheISA::IPR_PALtemp16) >> 8) & 0xff; + int cpu = pkt.req->getCpuNum(); + Addr daddr = pkt.addr - BARAddrs[0]; Addr index = daddr >> Regs::VirtualShift; Addr raddr = daddr & Regs::VirtualMask; + pkt.time += pioDelay; + if (!regValid(raddr)) - panic("invalid address: cpu=%d da=%#x pa=%#x va=%#x size=%d", - cpu, daddr, req->paddr, req->vaddr, req->size); + panic("invalid register: cpu=%d, da=%#x pa=%#x size=%d", + cpu, daddr, pkt.addr, pkt.size); const Regs::Info &info = regInfo(raddr); if (!info.write) panic("write %s (read only): " - "cpu=%d vnic=%d da=%#x pa=%#x va=%#x size=%d", - info.name, cpu, index, daddr, req->paddr, req->vaddr, req->size); + "cpu=%d vnic=%d da=%#x pa=%#x size=%d", + info.name, cpu, index, daddr, pkt.addr, pkt.size); - if (req->size != info.size) + if (pkt.size != info.size) panic("write %s (invalid size): " - "cpu=%d vnic=%d da=%#x pa=%#x va=%#x size=%d", - info.name, cpu, index, daddr, req->paddr, req->vaddr, req->size); + "cpu=%d vnic=%d da=%#x pa=%#x size=%d", + info.name, cpu, index, daddr, pkt.addr, pkt.size); - uint32_t reg32 = *(uint32_t *)data; - uint64_t reg64 = *(uint64_t *)data; VirtualReg &vnic = virtualRegs[index]; DPRINTF(EthernetPIO, - "write %s vnic %d: cpu=%d val=%#x da=%#x pa=%#x va=%#x size=%d\n", - info.name, index, cpu, info.size == 4 ? reg32 : reg64, daddr, - req->paddr, req->vaddr, req->size); + "write %s vnic %d: cpu=%d val=%#x da=%#x pa=%#x size=%d\n", + info.name, index, cpu, info.size == 4 ? pkt.get<uint32_t>() : + pkt.get<uint64_t>(), daddr, pkt.addr, pkt.size); prepareWrite(cpu, index); switch (raddr) { case Regs::Config: - changeConfig(reg32); + changeConfig(pkt.get<uint32_t>()); break; case Regs::Command: - command(reg32); + command(pkt.get<uint32_t>()); break; case Regs::IntrStatus: - devIntrClear(regs.IntrStatus & reg32); + devIntrClear(regs.IntrStatus & pkt.get<uint32_t>()); break; case Regs::IntrMask: - devIntrChangeMask(reg32); + devIntrChangeMask(pkt.get<uint32_t>()); break; case Regs::RxData: @@ -530,7 +460,7 @@ Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data) vnic.rxUnique = rxUnique++; vnic.RxDone = Regs::RxDone_Busy; - vnic.RxData = reg64; + vnic.RxData = pkt.get<uint64_t>(); if (Regs::get_RxData_Vaddr(reg64)) { Addr vaddr = Regs::get_RxData_Addr(reg64); @@ -566,16 +496,16 @@ Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data) vnic.txUnique = txUnique++; vnic.TxDone = Regs::TxDone_Busy; - vnic.TxData = reg64; - if (Regs::get_TxData_Vaddr(reg64)) { - Addr vaddr = Regs::get_TxData_Addr(reg64); + if (Regs::get_TxData_Vaddr(pkt.get<uint64_t>())) { + panic("vtophys won't work here in newmem.\n"); + /*Addr vaddr = Regs::get_TxData_Addr(reg64); Addr paddr = vtophys(req->xc, vaddr); DPRINTF(EthernetPIO, "write TxData vnic %d (rxunique %d): " "vaddr=%#x, paddr=%#x\n", index, vnic.txUnique, vaddr, paddr); - vnic.TxData = Regs::set_TxData_Addr(vnic.TxData, paddr); + vnic.TxData = Regs::set_TxData_Addr(vnic.TxData, paddr);*/ } else { DPRINTF(EthernetPIO, "write TxData vnic %d (rxunique %d)\n", index, vnic.txUnique); @@ -590,7 +520,7 @@ Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data) break; } - return NoFault; + return pioDelay; } void @@ -850,22 +780,13 @@ Device::reset() } void -Device::rxDmaCopy() +Device::rxDmaDone() { assert(rxState == rxCopy); rxState = rxCopyDone; - DPRINTF(EthernetDMA, "begin rx dma write paddr=%#x len=%d\n", - rxDmaAddr, rxDmaLen); - physmem->dma_write(rxDmaAddr, (uint8_t *)rxDmaData, rxDmaLen); DPRINTF(EthernetDMA, "end rx dma write paddr=%#x len=%d\n", rxDmaAddr, rxDmaLen); DDUMP(EthernetData, rxDmaData, rxDmaLen); -} - -void -Device::rxDmaDone() -{ - rxDmaCopy(); // If the transmit state machine has a pending DMA, let it go first if (txState == txBeginCopy) @@ -1001,34 +922,22 @@ Device::rxKick() break; case rxBeginCopy: - if (dmaInterface && dmaInterface->busy()) + if (dmaPending()) goto exit; - rxDmaAddr = plat->pciToDma(Regs::get_RxData_Addr(vnic->RxData)); - rxDmaLen = min<int>(Regs::get_RxData_Len(vnic->RxData), + rxDmaAddr = params()->platform->pciToDma( + Regs::get_RxData_Addr(vnic->RxData)); + rxDmaLen = std::min<int>(Regs::get_RxData_Len(vnic->RxData), vnic->rxPacketBytes); rxDmaData = (*vnic->rxPacket)->data + vnic->rxPacketOffset; rxState = rxCopy; - if (rxDmaAddr == 1LL) { rxState = rxCopyDone; break; } - if (dmaInterface) { - dmaInterface->doDMA(WriteInvalidate, rxDmaAddr, rxDmaLen, - curTick, &rxDmaEvent, true); - goto exit; - } - - if (dmaWriteDelay != 0 || dmaWriteFactor != 0) { - Tick factor = ((rxDmaLen + ULL(63)) >> ULL(6)) * dmaWriteFactor; - Tick start = curTick + dmaWriteDelay + factor; - rxDmaEvent.schedule(start); - goto exit; - } - rxDmaCopy(); + dmaWrite(rxDmaAddr, rxDmaLen, &rxDmaEvent, rxDmaData); break; case rxCopy: @@ -1095,20 +1004,13 @@ Device::rxKick() } void -Device::txDmaCopy() +Device::txDmaDone() { assert(txState == txCopy); txState = txCopyDone; - physmem->dma_read((uint8_t *)txDmaData, txDmaAddr, txDmaLen); DPRINTF(EthernetDMA, "tx dma read paddr=%#x len=%d\n", txDmaAddr, txDmaLen); DDUMP(EthernetData, txDmaData, txDmaLen); -} - -void -Device::txDmaDone() -{ - txDmaCopy(); // If the receive state machine has a pending DMA, let it go first if (rxState == rxBeginCopy) @@ -1126,7 +1028,7 @@ Device::transmit() } uint32_t interrupts; - PacketPtr packet = txFifo.front(); + EthPacketPtr packet = txFifo.front(); if (!interface->sendPacket(packet)) { DPRINTF(Ethernet, "Packet Transmit: failed txFifo available %d\n", txFifo.avail()); @@ -1194,7 +1096,7 @@ Device::txKick() assert(Regs::get_TxDone_Busy(vnic->TxDone)); if (!txPacket) { // Grab a new packet from the fifo. - txPacket = new PacketData(16384); + txPacket = new EthPacketData(16384); txPacketOffset = 0; } @@ -1208,28 +1110,16 @@ Device::txKick() break; case txBeginCopy: - if (dmaInterface && dmaInterface->busy()) + if (dmaPending()) goto exit; - txDmaAddr = plat->pciToDma(Regs::get_TxData_Addr(vnic->TxData)); + txDmaAddr = params()->platform->pciToDma( + Regs::get_TxData_Addr(vnic->TxData)); txDmaLen = Regs::get_TxData_Len(vnic->TxData); txDmaData = txPacket->data + txPacketOffset; txState = txCopy; - if (dmaInterface) { - dmaInterface->doDMA(Read, txDmaAddr, txDmaLen, - curTick, &txDmaEvent, true); - goto exit; - } - - if (dmaReadDelay != 0 || dmaReadFactor != 0) { - Tick factor = ((txDmaLen + ULL(63)) >> ULL(6)) * dmaReadFactor; - Tick start = curTick + dmaReadDelay + factor; - txDmaEvent.schedule(start); - goto exit; - } - - txDmaCopy(); + dmaRead(txDmaAddr, txDmaLen, &txDmaEvent, txDmaData); break; case txCopy: @@ -1316,7 +1206,7 @@ Device::transferDone() } bool -Device::rxFilter(const PacketPtr &packet) +Device::rxFilter(const EthPacketPtr &packet) { if (!Regs::get_Config_Filter(regs.Config)) return false; @@ -1361,7 +1251,7 @@ Device::rxFilter(const PacketPtr &packet) } bool -Device::recvPacket(PacketPtr packet) +Device::recvPacket(EthPacketPtr packet) { rxBytes += packet->length; rxPackets++; @@ -1402,7 +1292,7 @@ Device::recvPacket(PacketPtr packet) // // void -Base::serialize(ostream &os) +Base::serialize(std::ostream &os) { // Serialize the PciDev base class PciDev::serialize(os); @@ -1446,7 +1336,7 @@ Base::unserialize(Checkpoint *cp, const std::string §ion) } void -Device::serialize(ostream &os) +Device::serialize(std::ostream &os) { int count; @@ -1484,7 +1374,7 @@ Device::serialize(ostream &os) for (int i = 0; i < virtualRegsSize; ++i) { VirtualReg *vnic = &virtualRegs[i]; - string reg = csprintf("vnic%d", i); + std::string reg = csprintf("vnic%d", i); paramOut(os, reg + ".RxData", vnic->RxData); paramOut(os, reg + ".RxDone", vnic->RxDone); paramOut(os, reg + ".TxData", vnic->TxData); @@ -1639,7 +1529,7 @@ Device::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(txPacketExists); txPacket = 0; if (txPacketExists) { - txPacket = new PacketData(16384); + txPacket = new EthPacketData(16384); txPacket->unserialize("txPacket", cp, section); UNSERIALIZE_SCALAR(txPacketOffset); UNSERIALIZE_SCALAR(txPacketBytes); @@ -1657,7 +1547,7 @@ Device::unserialize(Checkpoint *cp, const std::string §ion) virtualRegs.resize(virtualRegsSize); for (int i = 0; i < virtualRegsSize; ++i) { VirtualReg *vnic = &virtualRegs[i]; - string reg = csprintf("vnic%d", i); + std::string reg = csprintf("vnic%d", i); paramIn(cp, section, reg + ".RxData", vnic->RxData); paramIn(cp, section, reg + ".RxDone", vnic->RxDone); @@ -1693,28 +1583,11 @@ Device::unserialize(Checkpoint *cp, const std::string §ion) if (transmitTick) txEvent.schedule(curTick + transmitTick); - /* - * re-add addrRanges to bus bridges - */ - if (pioInterface) - pioInterface->addAddrRange(RangeSize(BARAddrs[0], BARSize[0])); -} - -Tick -Device::cacheAccess(MemReqPtr &req) -{ - Addr daddr; - int bar; - if (!getBAR(req->paddr, daddr, bar)) - panic("address does not map to a BAR pa=%#x va=%#x size=%d", - req->paddr, req->vaddr, req->size); + pioPort->sendStatusChange(Port::RangeChange); - DPRINTF(EthernetPIO, "timing %s to paddr=%#x bar=%d daddr=%#x\n", - req->cmd.toString(), req->paddr, bar, daddr); - - return curTick + pioLatency; } + BEGIN_DECLARE_SIM_OBJECT_PARAMS(Interface) SimObjectParam<EtherInt *> peer; @@ -1747,29 +1620,22 @@ REGISTER_SIM_OBJECT("SinicInt", Interface) BEGIN_DECLARE_SIM_OBJECT_PARAMS(Device) - Param<Tick> clock; - Param<Addr> addr; - SimObjectParam<MemoryController *> mmu; - SimObjectParam<PhysicalMemory *> physmem; + SimObjectParam<System *> system; + SimObjectParam<Platform *> platform; SimObjectParam<PciConfigAll *> configspace; SimObjectParam<PciConfigData *> configdata; - SimObjectParam<Platform *> platform; Param<uint32_t> pci_bus; Param<uint32_t> pci_dev; Param<uint32_t> pci_func; + Param<Tick> pio_latency; + Param<Tick> intr_delay; - SimObjectParam<HierParams *> hier; - SimObjectParam<Bus*> pio_bus; - SimObjectParam<Bus*> dma_bus; - SimObjectParam<Bus*> payload_bus; + Param<Tick> clock; Param<Tick> dma_read_delay; Param<Tick> dma_read_factor; Param<Tick> dma_write_delay; Param<Tick> dma_write_factor; - Param<bool> dma_no_allocate; - Param<Tick> pio_latency; - Param<Tick> intr_delay; Param<Tick> rx_delay; Param<Tick> tx_delay; @@ -1784,7 +1650,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Device) Param<uint32_t> tx_fifo_threshold; Param<bool> rx_filter; - Param<string> hardware_address; + Param<std::string> hardware_address; Param<bool> rx_thread; Param<bool> tx_thread; Param<bool> rss; @@ -1797,29 +1663,22 @@ END_DECLARE_SIM_OBJECT_PARAMS(Device) BEGIN_INIT_SIM_OBJECT_PARAMS(Device) - INIT_PARAM(clock, "State machine cycle time"), - INIT_PARAM(addr, "Device Address"), - INIT_PARAM(mmu, "Memory Controller"), - INIT_PARAM(physmem, "Physical Memory"), + INIT_PARAM(system, "System pointer"), + INIT_PARAM(platform, "Platform pointer"), INIT_PARAM(configspace, "PCI Configspace"), INIT_PARAM(configdata, "PCI Config data"), - INIT_PARAM(platform, "Platform"), - INIT_PARAM(pci_bus, "PCI bus"), + INIT_PARAM(pci_bus, "PCI bus ID"), INIT_PARAM(pci_dev, "PCI device number"), INIT_PARAM(pci_func, "PCI function code"), + INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1), + INIT_PARAM(intr_delay, "Interrupt Delay"), + INIT_PARAM(clock, "State machine cycle time"), - INIT_PARAM(hier, "Hierarchy global variables"), - INIT_PARAM(pio_bus, ""), - INIT_PARAM(dma_bus, ""), - INIT_PARAM(payload_bus, "The IO Bus to attach to for payload"), INIT_PARAM(dma_read_delay, "fixed delay for dma reads"), INIT_PARAM(dma_read_factor, "multiplier for dma reads"), INIT_PARAM(dma_write_delay, "fixed delay for dma writes"), INIT_PARAM(dma_write_factor, "multiplier for dma writes"), - INIT_PARAM(dma_no_allocate, "Should we allocat on read in cache"), - INIT_PARAM(pio_latency, "Programmed IO latency in bus cycles"), - INIT_PARAM(intr_delay, "Interrupt Delay"), INIT_PARAM(rx_delay, "Receive Delay"), INIT_PARAM(tx_delay, "Transmit Delay"), @@ -1849,31 +1708,22 @@ END_INIT_SIM_OBJECT_PARAMS(Device) CREATE_SIM_OBJECT(Device) { Device::Params *params = new Device::Params; - params->name = getInstanceName(); - - params->clock = clock; - - params->mmu = mmu; - params->physmem = physmem; + params->platform = platform; + params->system = system; params->configSpace = configspace; params->configData = configdata; - params->plat = platform; params->busNum = pci_bus; params->deviceNum = pci_dev; params->functionNum = pci_func; + params->pio_delay = pio_latency; + params->intr_delay = intr_delay; + params->clock = clock; - params->hier = hier; - params->pio_bus = pio_bus; - params->header_bus = dma_bus; - params->payload_bus = payload_bus; params->dma_read_delay = dma_read_delay; params->dma_read_factor = dma_read_factor; params->dma_write_delay = dma_write_delay; params->dma_write_factor = dma_write_factor; - params->dma_no_allocate = dma_no_allocate; - params->pio_latency = pio_latency; - params->intr_delay = intr_delay; params->tx_delay = tx_delay; params->rx_delay = rx_delay; diff --git a/dev/sinic.hh b/dev/sinic.hh index 892b3ab69..a786c3e44 100644 --- a/dev/sinic.hh +++ b/dev/sinic.hh @@ -37,7 +37,6 @@ #include "dev/pcidev.hh" #include "dev/pktfifo.hh" #include "dev/sinicreg.hh" -#include "mem/bus/bus.hh" #include "sim/eventq.hh" namespace Sinic { @@ -91,10 +90,6 @@ class Base : public PciDev class Device : public Base { protected: - Platform *plat; - PhysicalMemory *physmem; - - protected: /** Receive State Machine States */ enum RxState { rxIdle, @@ -169,10 +164,6 @@ class Device : public Base uint32_t ®Data32(Addr daddr) { return *(uint32_t *)®Data8(daddr); } uint64_t ®Data64(Addr daddr) { return *(uint64_t *)®Data8(daddr); } - private: - Addr addr; - static const Addr size = Regs::Size; - protected: RxState rxState; PacketFifo rxFifo; @@ -186,7 +177,7 @@ class Device : public Base TxState txState; PacketFifo txFifo; bool txFull; - PacketPtr txPacket; + EthPacketPtr txPacket; int txPacketOffset; int txPacketBytes; Addr txDmaAddr; @@ -226,7 +217,7 @@ class Device : public Base /** * receive address filter */ - bool rxFilter(const PacketPtr &packet); + bool rxFilter(const EthPacketPtr &packet); /** * device configuration @@ -238,7 +229,7 @@ class Device : public Base * device ethernet interface */ public: - bool recvPacket(PacketPtr packet); + bool recvPacket(EthPacketPtr packet); void transferDone(); void setInterface(Interface *i) { assert(!interface); interface = i; } @@ -246,12 +237,10 @@ class Device : public Base * DMA parameters */ protected: - void rxDmaCopy(); void rxDmaDone(); friend class EventWrapper<Device, &Device::rxDmaDone>; EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent; - void txDmaCopy(); void txDmaDone(); friend class EventWrapper<Device, &Device::txDmaDone>; EventWrapper<Device, &Device::txDmaDone> txDmaEvent; @@ -270,25 +259,16 @@ class Device : public Base void devIntrChangeMask(uint32_t newmask); /** - * PCI Configuration interface - */ - public: - virtual void writeConfig(int offset, int size, const uint8_t *data); - -/** * Memory Interface */ public: - virtual Fault read(MemReqPtr &req, uint8_t *data); - virtual Fault write(MemReqPtr &req, const uint8_t *data); + virtual Tick read(Packet &pkt); + virtual Tick write(Packet &pkt); void prepareIO(int cpu, int index); void prepareRead(int cpu, int index); void prepareWrite(int cpu, int index); - Fault iprRead(Addr daddr, int cpu, uint64_t &result); - Fault readBar0(MemReqPtr &req, Addr daddr, uint8_t *data); - Fault writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data); - Tick cacheAccess(MemReqPtr &req); + // Fault iprRead(Addr daddr, int cpu, uint64_t &result); /** * Statistics @@ -336,17 +316,8 @@ class Device : public Base public: struct Params : public Base::Params { - IntrControl *i; - PhysicalMemory *pmem; Tick tx_delay; Tick rx_delay; - HierParams *hier; - Bus *pio_bus; - Bus *header_bus; - Bus *payload_bus; - Tick pio_latency; - PhysicalMemory *physmem; - IntrControl *intctrl; bool rx_filter; Net::EthAddr eaddr; uint32_t rx_max_copy; @@ -362,7 +333,6 @@ class Device : public Base Tick dma_read_factor; Tick dma_write_delay; Tick dma_write_factor; - bool dma_no_allocate; bool rx_thread; bool tx_thread; bool rss; @@ -392,7 +362,7 @@ class Interface : public EtherInt Interface(const std::string &name, Device *d) : EtherInt(name), dev(d) { dev->setInterface(this); } - virtual bool recvPacket(PacketPtr pkt) { return dev->recvPacket(pkt); } + virtual bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); } virtual void sendDone() { dev->transferDone(); } }; diff --git a/dev/tsunami.cc b/dev/tsunami.cc index 58fc7434e..ed011531d 100644 --- a/dev/tsunami.cc +++ b/dev/tsunami.cc @@ -36,12 +36,10 @@ #include "cpu/intr_control.hh" #include "dev/simconsole.hh" -#include "dev/ide_ctrl.hh" #include "dev/tsunami_cchip.hh" #include "dev/tsunami_pchip.hh" #include "dev/tsunami_io.hh" #include "dev/tsunami.hh" -#include "dev/pciconfigall.hh" #include "sim/builder.hh" #include "sim/system.hh" @@ -49,9 +47,8 @@ using namespace std; //Should this be AlphaISA? using namespace TheISA; -Tsunami::Tsunami(const string &name, System *s, IntrControl *ic, - PciConfigAll *pci) - : Platform(name, ic, pci), system(s) +Tsunami::Tsunami(const string &name, System *s, IntrControl *ic) + : Platform(name, ic), system(s) { // set the back pointer from the system to myself system->platform = this; @@ -112,21 +109,19 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tsunami) SimObjectParam<System *> system; SimObjectParam<IntrControl *> intrctrl; - SimObjectParam<PciConfigAll *> pciconfig; END_DECLARE_SIM_OBJECT_PARAMS(Tsunami) BEGIN_INIT_SIM_OBJECT_PARAMS(Tsunami) INIT_PARAM(system, "system"), - INIT_PARAM(intrctrl, "interrupt controller"), - INIT_PARAM(pciconfig, "PCI configuration") + INIT_PARAM(intrctrl, "interrupt controller") END_INIT_SIM_OBJECT_PARAMS(Tsunami) CREATE_SIM_OBJECT(Tsunami) { - return new Tsunami(getInstanceName(), system, intrctrl, pciconfig); + return new Tsunami(getInstanceName(), system, intrctrl); } REGISTER_SIM_OBJECT("Tsunami", Tsunami) diff --git a/dev/tsunami.hh b/dev/tsunami.hh index 7fd91d5b2..668c82674 100644 --- a/dev/tsunami.hh +++ b/dev/tsunami.hh @@ -38,12 +38,9 @@ #include "dev/platform.hh" class IdeController; -class TlaserClock; -class NSGigE; class TsunamiCChip; class TsunamiPChip; class TsunamiIO; -class PciConfigAll; class System; /** @@ -86,8 +83,7 @@ class Tsunami : public Platform * @param name name of the object * @param intrctrl pointer to the interrupt controller */ - Tsunami(const std::string &name, System *s, IntrControl *intctrl, - PciConfigAll *pci); + Tsunami(const std::string &name, System *s, IntrControl *intctrl); /** * Return the interrupting frequency to AlphaAccess diff --git a/dev/tsunami_cchip.cc b/dev/tsunami_cchip.cc index 2649fe27a..7b9032f6e 100644 --- a/dev/tsunami_cchip.cc +++ b/dev/tsunami_cchip.cc @@ -34,14 +34,12 @@ #include <string> #include <vector> +#include "arch/alpha/ev5.hh" #include "base/trace.hh" #include "dev/tsunami_cchip.hh" #include "dev/tsunamireg.h" #include "dev/tsunami.hh" -#include "mem/bus/bus.hh" -#include "mem/bus/pio_interface.hh" -#include "mem/bus/pio_interface_impl.hh" -#include "mem/functional/memory_control.hh" +#include "mem/port.hh" #include "cpu/exec_context.hh" #include "cpu/intr_control.hh" #include "sim/builder.hh" @@ -51,19 +49,10 @@ using namespace std; //Should this be AlphaISA? using namespace TheISA; -TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a, - MemoryController *mmu, HierParams *hier, - Bus* pio_bus, Tick pio_latency) - : PioDevice(name, t), addr(a), tsunami(t) +TsunamiCChip::TsunamiCChip(Params *p) + : BasicPioDevice(p), tsunami(p->tsunami) { - mmu->add_child(this, RangeSize(addr, size)); - - if (pio_bus) { - pioInterface = newPioInterface(name + ".pio", hier, pio_bus, this, - &TsunamiCChip::cacheAccess); - pioInterface->addAddrRange(RangeSize(addr, size)); - pioLatency = pio_latency * pio_bus->clockRate; - } + pioSize = 0xfffffff; drir = 0; ipint = 0; @@ -79,315 +68,302 @@ TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a, tsunami->cchip = this; } -Fault -TsunamiCChip::read(MemReqPtr &req, uint8_t *data) +Tick +TsunamiCChip::read(Packet &pkt) { - DPRINTF(Tsunami, "read va=%#x size=%d\n", req->vaddr, req->size); + DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt.addr, pkt.size); - Addr regnum = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6; - Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); + assert(pkt.result == Unknown); + assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); - ExecContext *xc = req->xc; + pkt.time += pioDelay; + Addr regnum = (pkt.addr - pioAddr) >> 6; + Addr daddr = (pkt.addr - pioAddr); - switch (req->size) { + pkt.allocate(); + switch (pkt.size) { case sizeof(uint64_t): if (daddr & TSDEV_CC_BDIMS) { - *(uint64_t*)data = dim[(daddr >> 4) & 0x3F]; - return NoFault; + pkt.set(dim[(daddr >> 4) & 0x3F]); + break; } if (daddr & TSDEV_CC_BDIRS) { - *(uint64_t*)data = dir[(daddr >> 4) & 0x3F]; - return NoFault; + pkt.set(dir[(daddr >> 4) & 0x3F]); + break; } switch(regnum) { case TSDEV_CC_CSR: - *(uint64_t*)data = 0x0; - return NoFault; + pkt.set(0x0); + break; case TSDEV_CC_MTR: panic("TSDEV_CC_MTR not implemeted\n"); - return NoFault; + break; case TSDEV_CC_MISC: - *(uint64_t*)data = (ipint << 8) & 0xF | - (itint << 4) & 0xF | - (xc->readCpuId() & 0x3); - return NoFault; + pkt.set((ipint << 8) & 0xF | (itint << 4) & 0xF | + (pkt.req->getCpuNum() & 0x3)); + break; case TSDEV_CC_AAR0: case TSDEV_CC_AAR1: case TSDEV_CC_AAR2: case TSDEV_CC_AAR3: - *(uint64_t*)data = 0; - return NoFault; + pkt.set(0); + break; case TSDEV_CC_DIM0: - *(uint64_t*)data = dim[0]; - return NoFault; + pkt.set(dim[0]); + break; case TSDEV_CC_DIM1: - *(uint64_t*)data = dim[1]; - return NoFault; + pkt.set(dim[1]); + break; case TSDEV_CC_DIM2: - *(uint64_t*)data = dim[2]; - return NoFault; + pkt.set(dim[2]); + break; case TSDEV_CC_DIM3: - *(uint64_t*)data = dim[3]; - return NoFault; + pkt.set(dim[3]); + break; case TSDEV_CC_DIR0: - *(uint64_t*)data = dir[0]; - return NoFault; + pkt.set(dir[0]); + break; case TSDEV_CC_DIR1: - *(uint64_t*)data = dir[1]; - return NoFault; + pkt.set(dir[1]); + break; case TSDEV_CC_DIR2: - *(uint64_t*)data = dir[2]; - return NoFault; + pkt.set(dir[2]); + break; case TSDEV_CC_DIR3: - *(uint64_t*)data = dir[3]; - return NoFault; + pkt.set(dir[3]); + break; case TSDEV_CC_DRIR: - *(uint64_t*)data = drir; - return NoFault; + pkt.set(drir); + break; case TSDEV_CC_PRBEN: panic("TSDEV_CC_PRBEN not implemented\n"); - return NoFault; + break; case TSDEV_CC_IIC0: case TSDEV_CC_IIC1: case TSDEV_CC_IIC2: case TSDEV_CC_IIC3: panic("TSDEV_CC_IICx not implemented\n"); - return NoFault; + break; case TSDEV_CC_MPR0: case TSDEV_CC_MPR1: case TSDEV_CC_MPR2: case TSDEV_CC_MPR3: panic("TSDEV_CC_MPRx not implemented\n"); - return NoFault; + break; case TSDEV_CC_IPIR: - *(uint64_t*)data = ipint; - return NoFault; + pkt.set(ipint); + break; case TSDEV_CC_ITIR: - *(uint64_t*)data = itint; - return NoFault; + pkt.set(itint); + break; default: panic("default in cchip read reached, accessing 0x%x\n"); } // uint64_t break; case sizeof(uint32_t): - if (regnum == TSDEV_CC_DRIR) { - warn("accessing DRIR with 32 bit read, " - "hopefully your just reading this for timing"); - *(uint32_t*)data = drir; - } else - panic("invalid access size(?) for tsunami register!\n"); - return NoFault; case sizeof(uint16_t): case sizeof(uint8_t): default: panic("invalid access size(?) for tsunami register!\n"); } - DPRINTFN("Tsunami CChip ERROR: read regnum=%#x size=%d\n", regnum, req->size); + DPRINTF(Tsunami, "Tsunami CChip: read regnum=%#x size=%d data=%lld\n", + regnum, pkt.size, pkt.get<uint64_t>()); - return NoFault; + pkt.result = Success; + return pioDelay; } -Fault -TsunamiCChip::write(MemReqPtr &req, const uint8_t *data) +Tick +TsunamiCChip::write(Packet &pkt) { - DPRINTF(Tsunami, "write - va=%#x value=%#x size=%d \n", - req->vaddr, *(uint64_t*)data, req->size); + pkt.time += pioDelay; - Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); - Addr regnum = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6; - bool supportedWrite = false; + assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); + Addr daddr = pkt.addr - pioAddr; + Addr regnum = (pkt.addr - pioAddr) >> 6 ; - switch (req->size) { - case sizeof(uint64_t): - if (daddr & TSDEV_CC_BDIMS) - { - int number = (daddr >> 4) & 0x3F; - - uint64_t bitvector; - uint64_t olddim; - uint64_t olddir; - - olddim = dim[number]; - olddir = dir[number]; - dim[number] = *(uint64_t*)data; - dir[number] = dim[number] & drir; - for(int x = 0; x < Tsunami::Max_CPUs; x++) - { - bitvector = ULL(1) << x; - // Figure out which bits have changed - if ((dim[number] & bitvector) != (olddim & bitvector)) - { - // The bit is now set and it wasn't before (set) - if((dim[number] & bitvector) && (dir[number] & bitvector)) - { - tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x); - DPRINTF(Tsunami, "dim write resulting in posting dir" - " interrupt to cpu %d\n", number); - } - else if ((olddir & bitvector) && - !(dir[number] & bitvector)) - { - // The bit was set and now its now clear and - // we were interrupting on that bit before - tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x); - DPRINTF(Tsunami, "dim write resulting in clear" - " dir interrupt to cpu %d\n", number); + assert(pkt.size == sizeof(uint64_t)); - } + DPRINTF(Tsunami, "write - addr=%#x value=%#x\n", pkt.addr, pkt.get<uint64_t>()); + bool supportedWrite = false; - } - } - return NoFault; - } - switch(regnum) { - case TSDEV_CC_CSR: - panic("TSDEV_CC_CSR write\n"); - return NoFault; - case TSDEV_CC_MTR: - panic("TSDEV_CC_MTR write not implemented\n"); - return NoFault; - case TSDEV_CC_MISC: - uint64_t ipreq; - ipreq = (*(uint64_t*)data >> 12) & 0xF; - //If it is bit 12-15, this is an IPI post - if (ipreq) { - reqIPI(ipreq); - supportedWrite = true; + if (daddr & TSDEV_CC_BDIMS) + { + int number = (daddr >> 4) & 0x3F; + + uint64_t bitvector; + uint64_t olddim; + uint64_t olddir; + + olddim = dim[number]; + olddir = dir[number]; + dim[number] = pkt.get<uint64_t>(); + dir[number] = dim[number] & drir; + for(int x = 0; x < Tsunami::Max_CPUs; x++) + { + bitvector = ULL(1) << x; + // Figure out which bits have changed + if ((dim[number] & bitvector) != (olddim & bitvector)) + { + // The bit is now set and it wasn't before (set) + if((dim[number] & bitvector) && (dir[number] & bitvector)) + { + tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x); + DPRINTF(Tsunami, "dim write resulting in posting dir" + " interrupt to cpu %d\n", number); } + else if ((olddir & bitvector) && + !(dir[number] & bitvector)) + { + // The bit was set and now its now clear and + // we were interrupting on that bit before + tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x); + DPRINTF(Tsunami, "dim write resulting in clear" + " dir interrupt to cpu %d\n", number); - //If it is bit 8-11, this is an IPI clear - uint64_t ipintr; - ipintr = (*(uint64_t*)data >> 8) & 0xF; - if (ipintr) { - clearIPI(ipintr); - supportedWrite = true; } - //If it is the 4-7th bit, clear the RTC interrupt - uint64_t itintr; - itintr = (*(uint64_t*)data >> 4) & 0xF; - if (itintr) { - clearITI(itintr); - supportedWrite = true; - } - // ignore NXMs - if (*(uint64_t*)data & 0x10000000) - supportedWrite = true; + } + } + } else { + switch(regnum) { + case TSDEV_CC_CSR: + panic("TSDEV_CC_CSR write\n"); + case TSDEV_CC_MTR: + panic("TSDEV_CC_MTR write not implemented\n"); + case TSDEV_CC_MISC: + uint64_t ipreq; + ipreq = (pkt.get<uint64_t>() >> 12) & 0xF; + //If it is bit 12-15, this is an IPI post + if (ipreq) { + reqIPI(ipreq); + supportedWrite = true; + } - if(!supportedWrite) - panic("TSDEV_CC_MISC write not implemented\n"); + //If it is bit 8-11, this is an IPI clear + uint64_t ipintr; + ipintr = (pkt.get<uint64_t>() >> 8) & 0xF; + if (ipintr) { + clearIPI(ipintr); + supportedWrite = true; + } - return NoFault; - case TSDEV_CC_AAR0: - case TSDEV_CC_AAR1: - case TSDEV_CC_AAR2: - case TSDEV_CC_AAR3: - panic("TSDEV_CC_AARx write not implemeted\n"); - return NoFault; - case TSDEV_CC_DIM0: - case TSDEV_CC_DIM1: - case TSDEV_CC_DIM2: - case TSDEV_CC_DIM3: - int number; - if(regnum == TSDEV_CC_DIM0) - number = 0; - else if(regnum == TSDEV_CC_DIM1) - number = 1; - else if(regnum == TSDEV_CC_DIM2) - number = 2; - else - number = 3; - - uint64_t bitvector; - uint64_t olddim; - uint64_t olddir; - - olddim = dim[number]; - olddir = dir[number]; - dim[number] = *(uint64_t*)data; - dir[number] = dim[number] & drir; - for(int x = 0; x < 64; x++) - { - bitvector = ULL(1) << x; - // Figure out which bits have changed - if ((dim[number] & bitvector) != (olddim & bitvector)) - { - // The bit is now set and it wasn't before (set) - if((dim[number] & bitvector) && (dir[number] & bitvector)) - { - tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x); - DPRINTF(Tsunami, "posting dir interrupt to cpu 0\n"); - } - else if ((olddir & bitvector) && - !(dir[number] & bitvector)) - { - // The bit was set and now its now clear and - // we were interrupting on that bit before - tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x); - DPRINTF(Tsunami, "dim write resulting in clear" - " dir interrupt to cpu %d\n", - x); - - } - - - } - } - return NoFault; - case TSDEV_CC_DIR0: - case TSDEV_CC_DIR1: - case TSDEV_CC_DIR2: - case TSDEV_CC_DIR3: - panic("TSDEV_CC_DIR write not implemented\n"); - case TSDEV_CC_DRIR: - panic("TSDEV_CC_DRIR write not implemented\n"); - case TSDEV_CC_PRBEN: - panic("TSDEV_CC_PRBEN write not implemented\n"); - case TSDEV_CC_IIC0: - case TSDEV_CC_IIC1: - case TSDEV_CC_IIC2: - case TSDEV_CC_IIC3: - panic("TSDEV_CC_IICx write not implemented\n"); - case TSDEV_CC_MPR0: - case TSDEV_CC_MPR1: - case TSDEV_CC_MPR2: - case TSDEV_CC_MPR3: - panic("TSDEV_CC_MPRx write not implemented\n"); - case TSDEV_CC_IPIR: - clearIPI(*(uint64_t*)data); - return NoFault; - case TSDEV_CC_ITIR: - clearITI(*(uint64_t*)data); - return NoFault; - case TSDEV_CC_IPIQ: - reqIPI(*(uint64_t*)data); - return NoFault; - default: - panic("default in cchip read reached, accessing 0x%x\n"); - } + //If it is the 4-7th bit, clear the RTC interrupt + uint64_t itintr; + itintr = (pkt.get<uint64_t>() >> 4) & 0xF; + if (itintr) { + clearITI(itintr); + supportedWrite = true; + } - break; - case sizeof(uint32_t): - case sizeof(uint16_t): - case sizeof(uint8_t): - default: - panic("invalid access size(?) for tsunami register!\n"); - } + // ignore NXMs + if (pkt.get<uint64_t>() & 0x10000000) + supportedWrite = true; + + if(!supportedWrite) + panic("TSDEV_CC_MISC write not implemented\n"); + + break; + case TSDEV_CC_AAR0: + case TSDEV_CC_AAR1: + case TSDEV_CC_AAR2: + case TSDEV_CC_AAR3: + panic("TSDEV_CC_AARx write not implemeted\n"); + case TSDEV_CC_DIM0: + case TSDEV_CC_DIM1: + case TSDEV_CC_DIM2: + case TSDEV_CC_DIM3: + int number; + if(regnum == TSDEV_CC_DIM0) + number = 0; + else if(regnum == TSDEV_CC_DIM1) + number = 1; + else if(regnum == TSDEV_CC_DIM2) + number = 2; + else + number = 3; + + uint64_t bitvector; + uint64_t olddim; + uint64_t olddir; + + olddim = dim[number]; + olddir = dir[number]; + dim[number] = pkt.get<uint64_t>(); + dir[number] = dim[number] & drir; + for(int x = 0; x < 64; x++) + { + bitvector = ULL(1) << x; + // Figure out which bits have changed + if ((dim[number] & bitvector) != (olddim & bitvector)) + { + // The bit is now set and it wasn't before (set) + if((dim[number] & bitvector) && (dir[number] & bitvector)) + { + tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x); + DPRINTF(Tsunami, "posting dir interrupt to cpu 0\n"); + } + else if ((olddir & bitvector) && + !(dir[number] & bitvector)) + { + // The bit was set and now its now clear and + // we were interrupting on that bit before + tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x); + DPRINTF(Tsunami, "dim write resulting in clear" + " dir interrupt to cpu %d\n", + x); + + } - DPRINTFN("Tsunami ERROR: write daddr=%#x size=%d\n", daddr, req->size); - return NoFault; + } + } + break; + case TSDEV_CC_DIR0: + case TSDEV_CC_DIR1: + case TSDEV_CC_DIR2: + case TSDEV_CC_DIR3: + panic("TSDEV_CC_DIR write not implemented\n"); + case TSDEV_CC_DRIR: + panic("TSDEV_CC_DRIR write not implemented\n"); + case TSDEV_CC_PRBEN: + panic("TSDEV_CC_PRBEN write not implemented\n"); + case TSDEV_CC_IIC0: + case TSDEV_CC_IIC1: + case TSDEV_CC_IIC2: + case TSDEV_CC_IIC3: + panic("TSDEV_CC_IICx write not implemented\n"); + case TSDEV_CC_MPR0: + case TSDEV_CC_MPR1: + case TSDEV_CC_MPR2: + case TSDEV_CC_MPR3: + panic("TSDEV_CC_MPRx write not implemented\n"); + case TSDEV_CC_IPIR: + clearIPI(pkt.get<uint64_t>()); + break; + case TSDEV_CC_ITIR: + clearITI(pkt.get<uint64_t>()); + break; + case TSDEV_CC_IPIQ: + reqIPI(pkt.get<uint64_t>()); + break; + default: + panic("default in cchip read reached, accessing 0x%x\n"); + } // swtich(regnum) + } // not BIG_TSUNAMI write + pkt.result = Success; + return pioDelay; } void @@ -471,11 +447,11 @@ TsunamiCChip::postRTC() for (int i = 0; i < size; i++) { uint64_t cpumask = ULL(1) << i; - if (!(cpumask & itint)) { - itint |= cpumask; - tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ2, 0); - DPRINTF(Tsunami, "Posting RTC interrupt to cpu=%d", i); - } + if (!(cpumask & itint)) { + itint |= cpumask; + tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ2, 0); + DPRINTF(Tsunami, "Posting RTC interrupt to cpu=%d", i); + } } } @@ -490,11 +466,11 @@ TsunamiCChip::postDRIR(uint32_t interrupt) for(int i=0; i < size; i++) { dir[i] = dim[i] & drir; - if (dim[i] & bitvector) { - tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ1, interrupt); - DPRINTF(Tsunami, "posting dir interrupt to cpu %d," + if (dim[i] & bitvector) { + tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ1, interrupt); + DPRINTF(Tsunami, "posting dir interrupt to cpu %d," "interrupt %d\n",i, interrupt); - } + } } } @@ -509,25 +485,19 @@ TsunamiCChip::clearDRIR(uint32_t interrupt) { drir &= ~bitvector; for(int i=0; i < size; i++) { - if (dir[i] & bitvector) { - tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ1, interrupt); - DPRINTF(Tsunami, "clearing dir interrupt to cpu %d," + if (dir[i] & bitvector) { + tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ1, interrupt); + DPRINTF(Tsunami, "clearing dir interrupt to cpu %d," "interrupt %d\n",i, interrupt); - } - dir[i] = dim[i] & drir; + } + dir[i] = dim[i] & drir; } } else DPRINTF(Tsunami, "Spurrious clear? interrupt %d\n", interrupt); } -Tick -TsunamiCChip::cacheAccess(MemReqPtr &req) -{ - return curTick + pioLatency; -} - void TsunamiCChip::serialize(std::ostream &os) @@ -551,30 +521,34 @@ TsunamiCChip::unserialize(Checkpoint *cp, const std::string §ion) BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip) - SimObjectParam<Tsunami *> tsunami; - SimObjectParam<MemoryController *> mmu; - Param<Addr> addr; - SimObjectParam<Bus*> pio_bus; + Param<Addr> pio_addr; Param<Tick> pio_latency; - SimObjectParam<HierParams *> hier; + SimObjectParam<Platform *> platform; + SimObjectParam<System *> system; + SimObjectParam<Tsunami *> tsunami; END_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip) BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiCChip) - INIT_PARAM(tsunami, "Tsunami"), - INIT_PARAM(mmu, "Memory Controller"), - INIT_PARAM(addr, "Device Address"), - INIT_PARAM_DFLT(pio_bus, "The IO Bus to attach to", NULL), - INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1), - INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) + INIT_PARAM(pio_addr, "Device Address"), + INIT_PARAM(pio_latency, "Programmed IO latency"), + INIT_PARAM(platform, "platform"), + INIT_PARAM(system, "system object"), + INIT_PARAM(tsunami, "Tsunami") END_INIT_SIM_OBJECT_PARAMS(TsunamiCChip) CREATE_SIM_OBJECT(TsunamiCChip) { - return new TsunamiCChip(getInstanceName(), tsunami, addr, mmu, hier, - pio_bus, pio_latency); + TsunamiCChip::Params *p = new TsunamiCChip::Params; + p->name = getInstanceName(); + p->pio_addr = pio_addr; + p->pio_delay = pio_latency; + p->platform = platform; + p->system = system; + p->tsunami = tsunami; + return new TsunamiCChip(p); } REGISTER_SIM_OBJECT("TsunamiCChip", TsunamiCChip) diff --git a/dev/tsunami_cchip.hh b/dev/tsunami_cchip.hh index d88ad375f..6cd6cf13f 100644 --- a/dev/tsunami_cchip.hh +++ b/dev/tsunami_cchip.hh @@ -37,21 +37,13 @@ #include "base/range.hh" #include "dev/io_device.hh" -class MemoryController; /** * Tsunami CChip CSR Emulation. This device includes all the interrupt * handling code for the chipset. */ -class TsunamiCChip : public PioDevice +class TsunamiCChip : public BasicPioDevice { - private: - /** The base address of this device */ - Addr addr; - - /** The size of mappad from the above address */ - static const Addr size = 0xfffffff; - protected: /** * pointer to the tsunami object. @@ -85,36 +77,24 @@ class TsunamiCChip : public PioDevice uint64_t itint; public: + struct Params : public BasicPioDevice::Params + { + Tsunami *tsunami; + }; + protected: + const Params *params() const {return (const Params *)_params; } + + public: /** * Initialize the Tsunami CChip by setting all of the * device register to 0. - * @param name name of this device. - * @param t pointer back to the Tsunami object that we belong to. - * @param a address we are mapped at. - * @param mmu pointer to the memory controller that sends us events. - * @param hier object to store parameters universal the device hierarchy - * @param bus The bus that this device is attached to + * @param p params struct */ - TsunamiCChip(const std::string &name, Tsunami *t, Addr a, - MemoryController *mmu, HierParams *hier, Bus *pio_bus, - Tick pio_latency); - - /** - * Process a read to the CChip. - * @param req Contains the address to read from. - * @param data A pointer to write the read data to. - * @return The fault condition of the access. - */ - virtual Fault read(MemReqPtr &req, uint8_t *data); + TsunamiCChip(Params *p); + virtual Tick read(Packet &pkt); - /** - * Process a write to the CChip. - * @param req Contains the address to write to. - * @param data The data to write. - * @return The fault condition of the access. - */ - virtual Fault write(MemReqPtr &req, const uint8_t *data); + virtual Tick write(Packet &pkt); /** * post an RTC interrupt to the CPU @@ -165,12 +145,6 @@ class TsunamiCChip : public PioDevice */ virtual void unserialize(Checkpoint *cp, const std::string §ion); - /** - * Return how long this access will take. - * @param req the memory request to calcuate - * @return Tick when the request is done - */ - Tick cacheAccess(MemReqPtr &req); }; #endif // __TSUNAMI_CCHIP_HH__ diff --git a/dev/tsunami_io.cc b/dev/tsunami_io.cc index e66d6653b..0efcc1028 100644 --- a/dev/tsunami_io.cc +++ b/dev/tsunami_io.cc @@ -37,17 +37,15 @@ #include <vector> #include "base/trace.hh" -#include "dev/tsunami_io.hh" -#include "dev/tsunami.hh" #include "dev/pitreg.h" -#include "mem/bus/bus.hh" -#include "mem/bus/pio_interface.hh" -#include "mem/bus/pio_interface_impl.hh" -#include "sim/builder.hh" +#include "dev/rtcreg.h" #include "dev/tsunami_cchip.hh" +#include "dev/tsunami.hh" +#include "dev/tsunami_io.hh" #include "dev/tsunamireg.h" -#include "dev/rtcreg.h" -#include "mem/functional/memory_control.hh" +#include "mem/port.hh" +#include "sim/builder.hh" +#include "sim/system.hh" using namespace std; //Should this be AlphaISA? @@ -79,38 +77,38 @@ TsunamiIO::RTC::set_time(time_t t) } void -TsunamiIO::RTC::writeAddr(const uint8_t *data) +TsunamiIO::RTC::writeAddr(const uint8_t data) { - if (*data <= RTC_STAT_REGD) - addr = *data; + if (data <= RTC_STAT_REGD) + addr = data; else panic("RTC addresses over 0xD are not implemented.\n"); } void -TsunamiIO::RTC::writeData(const uint8_t *data) +TsunamiIO::RTC::writeData(const uint8_t data) { if (addr < RTC_STAT_REGA) - clock_data[addr] = *data; + clock_data[addr] = data; else { switch (addr) { case RTC_STAT_REGA: - if (*data != (RTCA_32768HZ | RTCA_1024HZ)) + if (data != (RTCA_32768HZ | RTCA_1024HZ)) panic("Unimplemented RTC register A value write!\n"); - stat_regA = *data; + stat_regA = data; break; case RTC_STAT_REGB: - if ((*data & ~(RTCB_PRDC_IE | RTCB_SQWE)) != (RTCB_BIN | RTCB_24HR)) + if ((data & ~(RTCB_PRDC_IE | RTCB_SQWE)) != (RTCB_BIN | RTCB_24HR)) panic("Write to RTC reg B bits that are not implemented!\n"); - if (*data & RTCB_PRDC_IE) { + if (data & RTCB_PRDC_IE) { if (!event.scheduled()) event.scheduleIntr(); } else { if (event.scheduled()) event.deschedule(); } - stat_regB = *data; + stat_regB = data; break; case RTC_STAT_REGC: case RTC_STAT_REGD: @@ -206,24 +204,24 @@ TsunamiIO::PITimer::PITimer(const string &name) } void -TsunamiIO::PITimer::writeControl(const uint8_t *data) +TsunamiIO::PITimer::writeControl(const uint8_t data) { int rw; int sel; - sel = GET_CTRL_SEL(*data); + sel = GET_CTRL_SEL(data); if (sel == PIT_READ_BACK) panic("PITimer Read-Back Command is not implemented.\n"); - rw = GET_CTRL_RW(*data); + rw = GET_CTRL_RW(data); if (rw == PIT_RW_LATCH_COMMAND) counter[sel]->latchCount(); else { counter[sel]->setRW(rw); - counter[sel]->setMode(GET_CTRL_MODE(*data)); - counter[sel]->setBCD(GET_CTRL_BCD(*data)); + counter[sel]->setMode(GET_CTRL_MODE(data)); + counter[sel]->setBCD(GET_CTRL_BCD(data)); } } @@ -295,11 +293,11 @@ TsunamiIO::PITimer::Counter::read(uint8_t *data) } void -TsunamiIO::PITimer::Counter::write(const uint8_t *data) +TsunamiIO::PITimer::Counter::write(const uint8_t data) { switch (write_byte) { case LSB: - count = (count & 0xFF00) | *data; + count = (count & 0xFF00) | data; if (event.scheduled()) event.deschedule(); @@ -308,7 +306,7 @@ TsunamiIO::PITimer::Counter::write(const uint8_t *data) break; case MSB: - count = (count & 0x00FF) | (*data << 8); + count = (count & 0x00FF) | (data << 8); period = count; if (period > 0) { @@ -416,26 +414,17 @@ TsunamiIO::PITimer::Counter::CounterEvent::description() return "tsunami 8254 Interval timer"; } -TsunamiIO::TsunamiIO(const string &name, Tsunami *t, time_t init_time, - Addr a, MemoryController *mmu, HierParams *hier, - Bus *pio_bus, Tick pio_latency, Tick ci) - : PioDevice(name, t), addr(a), clockInterval(ci), tsunami(t), - pitimer(name + "pitimer"), rtc(name + ".rtc", t, ci) +TsunamiIO::TsunamiIO(Params *p) + : BasicPioDevice(p), tsunami(p->tsunami), pitimer(p->name + "pitimer"), + rtc(p->name + ".rtc", p->tsunami, p->frequency) { - mmu->add_child(this, RangeSize(addr, size)); - - if (pio_bus) { - pioInterface = newPioInterface(name + ".pio", hier, pio_bus, this, - &TsunamiIO::cacheAccess); - pioInterface->addAddrRange(RangeSize(addr, size)); - pioLatency = pio_latency * pio_bus->clockRate; - } + pioSize = 0xff; // set the back pointer from tsunami to myself tsunami->io = this; timerData = 0; - rtc.set_time(init_time == 0 ? time(NULL) : init_time); + rtc.set_time(p->init_time == 0 ? time(NULL) : p->init_time); picr = 0; picInterrupting = false; } @@ -443,185 +432,156 @@ TsunamiIO::TsunamiIO(const string &name, Tsunami *t, time_t init_time, Tick TsunamiIO::frequency() const { - return Clock::Frequency / clockInterval; + return Clock::Frequency / params()->frequency; } -Fault -TsunamiIO::read(MemReqPtr &req, uint8_t *data) +Tick +TsunamiIO::read(Packet &pkt) { - DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n", - req->vaddr, req->size, req->vaddr & 0xfff); + assert(pkt.result == Unknown); + assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); + + pkt.time += pioDelay; + Addr daddr = pkt.addr - pioAddr; - Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); + DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n", pkt.addr, + pkt.size, daddr); + pkt.allocate(); - switch(req->size) { - case sizeof(uint8_t): + if (pkt.size == sizeof(uint8_t)) { switch(daddr) { // PIC1 mask read case TSDEV_PIC1_MASK: - *(uint8_t*)data = ~mask1; - return NoFault; + pkt.set(~mask1); + break; case TSDEV_PIC2_MASK: - *(uint8_t*)data = ~mask2; - return NoFault; + pkt.set(~mask2); + break; case TSDEV_PIC1_ISR: // !!! If this is modified 64bit case needs to be too // Pal code has to do a 64 bit physical read because there is // no load physical byte instruction - *(uint8_t*)data = picr; - return NoFault; + pkt.set(picr); + break; case TSDEV_PIC2_ISR: // PIC2 not implemnted... just return 0 - *(uint8_t*)data = 0x00; - return NoFault; + pkt.set(0x00); + break; case TSDEV_TMR0_DATA: - pitimer.counter0.read(data); - return NoFault; + pitimer.counter0.read(pkt.getPtr<uint8_t>()); + break; case TSDEV_TMR1_DATA: - pitimer.counter1.read(data); - return NoFault; + pitimer.counter1.read(pkt.getPtr<uint8_t>()); + break; case TSDEV_TMR2_DATA: - pitimer.counter2.read(data); - return NoFault; + pitimer.counter2.read(pkt.getPtr<uint8_t>()); + break; case TSDEV_RTC_DATA: - rtc.readData(data); - return NoFault; + rtc.readData(pkt.getPtr<uint8_t>()); + break; case TSDEV_CTRL_PORTB: if (pitimer.counter2.outputHigh()) - *data = PORTB_SPKR_HIGH; + pkt.set(PORTB_SPKR_HIGH); else - *data = 0x00; - return NoFault; + pkt.set(0x00); + break; default: - panic("I/O Read - va%#x size %d\n", req->vaddr, req->size); + panic("I/O Read - va%#x size %d\n", pkt.addr, pkt.size); } - case sizeof(uint16_t): - case sizeof(uint32_t): - panic("I/O Read - invalid size - va %#x size %d\n", - req->vaddr, req->size); - - case sizeof(uint64_t): - switch(daddr) { - case TSDEV_PIC1_ISR: - // !!! If this is modified 8bit case needs to be too - // Pal code has to do a 64 bit physical read because there is - // no load physical byte instruction - *(uint64_t*)data = (uint64_t)picr; - return NoFault; - default: - panic("I/O Read - invalid size - va %#x size %d\n", - req->vaddr, req->size); - } - - default: - panic("I/O Read - invalid size - va %#x size %d\n", - req->vaddr, req->size); + } else if (pkt.size == sizeof(uint64_t)) { + if (daddr == TSDEV_PIC1_ISR) + pkt.set<uint64_t>(picr); + else + panic("I/O Read - invalid addr - va %#x size %d\n", + pkt.addr, pkt.size); + } else { + panic("I/O Read - invalid size - va %#x size %d\n", pkt.addr, pkt.size); } - panic("I/O Read - va%#x size %d\n", req->vaddr, req->size); - - return NoFault; + pkt.result = Success; + return pioDelay; } -Fault -TsunamiIO::write(MemReqPtr &req, const uint8_t *data) +Tick +TsunamiIO::write(Packet &pkt) { + pkt.time += pioDelay; -#if TRACING_ON - uint8_t dt = *(uint8_t*)data; - uint64_t dt64 = dt; -#endif + assert(pkt.result == Unknown); + assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); + Addr daddr = pkt.addr - pioAddr; DPRINTF(Tsunami, "io write - va=%#x size=%d IOPort=%#x Data=%#x\n", - req->vaddr, req->size, req->vaddr & 0xfff, dt64); + pkt.addr, pkt.size, pkt.addr & 0xfff, (uint32_t)pkt.get<uint8_t>()); - Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); + assert(pkt.size == sizeof(uint8_t)); - switch(req->size) { - case sizeof(uint8_t): - switch(daddr) { - case TSDEV_PIC1_MASK: - mask1 = ~(*(uint8_t*)data); - if ((picr & mask1) && !picInterrupting) { - picInterrupting = true; - tsunami->cchip->postDRIR(55); - DPRINTF(Tsunami, "posting pic interrupt to cchip\n"); - } - if ((!(picr & mask1)) && picInterrupting) { - picInterrupting = false; - tsunami->cchip->clearDRIR(55); - DPRINTF(Tsunami, "clearing pic interrupt\n"); - } - return NoFault; - case TSDEV_PIC2_MASK: - mask2 = *(uint8_t*)data; - //PIC2 Not implemented to interrupt - return NoFault; - case TSDEV_PIC1_ACK: - // clear the interrupt on the PIC - picr &= ~(1 << (*(uint8_t*)data & 0xF)); - if (!(picr & mask1)) - tsunami->cchip->clearDRIR(55); - return NoFault; - case TSDEV_DMA1_CMND: - return NoFault; - case TSDEV_DMA2_CMND: - return NoFault; - case TSDEV_DMA1_MMASK: - return NoFault; - case TSDEV_DMA2_MMASK: - return NoFault; - case TSDEV_PIC2_ACK: - return NoFault; - case TSDEV_DMA1_RESET: - return NoFault; - case TSDEV_DMA2_RESET: - return NoFault; - case TSDEV_DMA1_MODE: - mode1 = *(uint8_t*)data; - return NoFault; - case TSDEV_DMA2_MODE: - mode2 = *(uint8_t*)data; - return NoFault; - case TSDEV_DMA1_MASK: - case TSDEV_DMA2_MASK: - return NoFault; - case TSDEV_TMR0_DATA: - pitimer.counter0.write(data); - return NoFault; - case TSDEV_TMR1_DATA: - pitimer.counter1.write(data); - return NoFault; - case TSDEV_TMR2_DATA: - pitimer.counter2.write(data); - return NoFault; - case TSDEV_TMR_CTRL: - pitimer.writeControl(data); - return NoFault; - case TSDEV_RTC_ADDR: - rtc.writeAddr(data); - return NoFault; - case TSDEV_KBD: - return NoFault; - case TSDEV_RTC_DATA: - rtc.writeData(data); - return NoFault; - case TSDEV_CTRL_PORTB: - // System Control Port B not implemented - return NoFault; - default: - panic("I/O Write - va%#x size %d data %#x\n", req->vaddr, req->size, (int)*data); + switch(daddr) { + case TSDEV_PIC1_MASK: + mask1 = ~(pkt.get<uint8_t>()); + if ((picr & mask1) && !picInterrupting) { + picInterrupting = true; + tsunami->cchip->postDRIR(55); + DPRINTF(Tsunami, "posting pic interrupt to cchip\n"); + } + if ((!(picr & mask1)) && picInterrupting) { + picInterrupting = false; + tsunami->cchip->clearDRIR(55); + DPRINTF(Tsunami, "clearing pic interrupt\n"); } - case sizeof(uint16_t): - case sizeof(uint32_t): - case sizeof(uint64_t): + break; + case TSDEV_PIC2_MASK: + mask2 = pkt.get<uint8_t>(); + //PIC2 Not implemented to interrupt + break; + case TSDEV_PIC1_ACK: + // clear the interrupt on the PIC + picr &= ~(1 << (pkt.get<uint8_t>() & 0xF)); + if (!(picr & mask1)) + tsunami->cchip->clearDRIR(55); + break; + case TSDEV_DMA1_MODE: + mode1 = pkt.get<uint8_t>(); + break; + case TSDEV_DMA2_MODE: + mode2 = pkt.get<uint8_t>(); + break; + case TSDEV_TMR0_DATA: + pitimer.counter0.write(pkt.get<uint8_t>()); + break; + case TSDEV_TMR1_DATA: + pitimer.counter1.write(pkt.get<uint8_t>()); + break; + case TSDEV_TMR2_DATA: + pitimer.counter2.write(pkt.get<uint8_t>()); + break; + case TSDEV_TMR_CTRL: + pitimer.writeControl(pkt.get<uint8_t>()); + break; + case TSDEV_RTC_ADDR: + rtc.writeAddr(pkt.get<uint8_t>()); + break; + case TSDEV_RTC_DATA: + rtc.writeData(pkt.get<uint8_t>()); + break; + case TSDEV_KBD: + case TSDEV_DMA1_CMND: + case TSDEV_DMA2_CMND: + case TSDEV_DMA1_MMASK: + case TSDEV_DMA2_MMASK: + case TSDEV_PIC2_ACK: + case TSDEV_DMA1_RESET: + case TSDEV_DMA2_RESET: + case TSDEV_DMA1_MASK: + case TSDEV_DMA2_MASK: + case TSDEV_CTRL_PORTB: + break; default: - panic("I/O Write - invalid size - va %#x size %d\n", - req->vaddr, req->size); + panic("I/O Write - va%#x size %d data %#x\n", pkt.addr, pkt.size, pkt.get<uint8_t>()); } - - return NoFault; + pkt.result = Success; + return pioDelay; } void @@ -646,12 +606,6 @@ TsunamiIO::clearPIC(uint8_t bitvector) } } -Tick -TsunamiIO::cacheAccess(MemReqPtr &req) -{ - return curTick + pioLatency; -} - void TsunamiIO::serialize(ostream &os) { @@ -686,34 +640,40 @@ TsunamiIO::unserialize(Checkpoint *cp, const string §ion) BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO) - SimObjectParam<Tsunami *> tsunami; - Param<time_t> time; - SimObjectParam<MemoryController *> mmu; - Param<Addr> addr; - SimObjectParam<Bus*> pio_bus; + Param<Addr> pio_addr; Param<Tick> pio_latency; - SimObjectParam<HierParams *> hier; Param<Tick> frequency; + SimObjectParam<Platform *> platform; + SimObjectParam<System *> system; + Param<time_t> time; + SimObjectParam<Tsunami *> tsunami; END_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO) BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiIO) - INIT_PARAM(tsunami, "Tsunami"), + INIT_PARAM(pio_addr, "Device Address"), + INIT_PARAM(pio_latency, "Programmed IO latency"), + INIT_PARAM(frequency, "clock interrupt frequency"), + INIT_PARAM(platform, "platform"), + INIT_PARAM(system, "system object"), INIT_PARAM(time, "System time to use (0 for actual time"), - INIT_PARAM(mmu, "Memory Controller"), - INIT_PARAM(addr, "Device Address"), - INIT_PARAM(pio_bus, "The IO Bus to attach to"), - INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1), - INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams), - INIT_PARAM(frequency, "clock interrupt frequency") + INIT_PARAM(tsunami, "Tsunami") END_INIT_SIM_OBJECT_PARAMS(TsunamiIO) CREATE_SIM_OBJECT(TsunamiIO) { - return new TsunamiIO(getInstanceName(), tsunami, time, addr, mmu, hier, - pio_bus, pio_latency, frequency); + TsunamiIO::Params *p = new TsunamiIO::Params; + p->frequency = frequency; + p->name = getInstanceName(); + p->pio_addr = pio_addr; + p->pio_delay = pio_latency; + p->platform = platform; + p->system = system; + p->init_time = time; + p->tsunami = tsunami; + return new TsunamiIO(p); } REGISTER_SIM_OBJECT("TsunamiIO", TsunamiIO) diff --git a/dev/tsunami_io.hh b/dev/tsunami_io.hh index b024ecd14..c37f3aa16 100644 --- a/dev/tsunami_io.hh +++ b/dev/tsunami_io.hh @@ -38,21 +38,13 @@ #include "dev/tsunami.hh" #include "sim/eventq.hh" -class MemoryController; - /** * Tsunami I/O device is a catch all for all the south bridge stuff we care * to implement. */ -class TsunamiIO : public PioDevice +class TsunamiIO : public BasicPioDevice { private: - /** The base address of this device */ - Addr addr; - - /** The size of mappad from the above address */ - static const Addr size = 0xff; - struct tm tm; protected: @@ -120,10 +112,10 @@ class TsunamiIO : public PioDevice void set_time(time_t t); /** RTC address port: write address of RTC RAM data to access */ - void writeAddr(const uint8_t *data); + void writeAddr(const uint8_t data); /** RTC write data */ - void writeData(const uint8_t *data); + void writeData(const uint8_t data); /** RTC read data */ void readData(uint8_t *data); @@ -218,7 +210,7 @@ class TsunamiIO : public PioDevice void read(uint8_t *data); /** Write a count byte */ - void write(const uint8_t *data); + void write(const uint8_t data); /** Is the output high? */ bool outputHigh(); @@ -254,7 +246,7 @@ class TsunamiIO : public PioDevice PITimer(const std::string &name); /** Write control word */ - void writeControl(const uint8_t* data); + void writeControl(const uint8_t data); /** * Serialize this object to the given output stream. @@ -289,8 +281,6 @@ class TsunamiIO : public PioDevice /** Is the pic interrupting right now or not. */ bool picInterrupting; - Tick clockInterval; - /** A pointer to the Tsunami device which be belong to */ Tsunami *tsunami; @@ -312,33 +302,24 @@ class TsunamiIO : public PioDevice */ Tick frequency() const; + struct Params : public BasicPioDevice::Params + { + Tick frequency; + Tsunami *tsunami; + time_t init_time; + }; + protected: + const Params *params() const { return (const Params*)_params; } + + public: /** * Initialize all the data for devices supported by Tsunami I/O. - * @param name name of this device. - * @param t pointer back to the Tsunami object that we belong to. - * @param init_time Time (as in seconds since 1970) to set RTC to. - * @param a address we are mapped at. - * @param mmu pointer to the memory controller that sends us events. + * @param p pointer to Params struct */ - TsunamiIO(const std::string &name, Tsunami *t, time_t init_time, - Addr a, MemoryController *mmu, HierParams *hier, Bus *pio_bus, - Tick pio_latency, Tick ci); + TsunamiIO(Params *p); - /** - * Process a read to one of the devices we are emulating. - * @param req Contains the address to read from. - * @param data A pointer to write the read data to. - * @return The fault condition of the access. - */ - virtual Fault read(MemReqPtr &req, uint8_t *data); - - /** - * Process a write to one of the devices we emulate. - * @param req Contains the address to write to. - * @param data The data to write. - * @return The fault condition of the access. - */ - virtual Fault write(MemReqPtr &req, const uint8_t *data); + virtual Tick read(Packet &pkt); + virtual Tick write(Packet &pkt); /** * Post an PIC interrupt to the CPU via the CChip @@ -365,7 +346,6 @@ class TsunamiIO : public PioDevice */ virtual void unserialize(Checkpoint *cp, const std::string §ion); - Tick cacheAccess(MemReqPtr &req); }; #endif // __DEV_TSUNAMI_IO_HH__ diff --git a/dev/tsunami_pchip.cc b/dev/tsunami_pchip.cc index 46efc3dfe..1323a0548 100644 --- a/dev/tsunami_pchip.cc +++ b/dev/tsunami_pchip.cc @@ -38,11 +38,7 @@ #include "dev/tsunami_pchip.hh" #include "dev/tsunamireg.h" #include "dev/tsunami.hh" -#include "mem/bus/bus.hh" -#include "mem/bus/pio_interface.hh" -#include "mem/bus/pio_interface_impl.hh" -#include "mem/functional/memory_control.hh" -#include "mem/functional/physical.hh" +#include "mem/packet.hh" #include "sim/builder.hh" #include "sim/system.hh" @@ -50,12 +46,10 @@ using namespace std; //Should this be AlphaISA? using namespace TheISA; -TsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, Addr a, - MemoryController *mmu, HierParams *hier, - Bus *pio_bus, Tick pio_latency) - : PioDevice(name, t), addr(a), tsunami(t) +TsunamiPChip::TsunamiPChip(Params *p) +: BasicPioDevice(p) { - mmu->add_child(this, RangeSize(addr, size)); + pioSize = 0xfff; for (int i = 0; i < 4; i++) { wsba[i] = 0; @@ -63,195 +57,175 @@ TsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, Addr a, tba[i] = 0; } - if (pio_bus) { - pioInterface = newPioInterface(name + ".pio", hier, pio_bus, this, - &TsunamiPChip::cacheAccess); - pioInterface->addAddrRange(RangeSize(addr, size)); - pioLatency = pio_latency * pio_bus->clockRate; - } - - // initialize pchip control register pctl = (ULL(0x1) << 20) | (ULL(0x1) << 32) | (ULL(0x2) << 36); //Set back pointer in tsunami - tsunami->pchip = this; + p->tsunami->pchip = this; } -Fault -TsunamiPChip::read(MemReqPtr &req, uint8_t *data) +Tick +TsunamiPChip::read(Packet &pkt) { - DPRINTF(Tsunami, "read va=%#x size=%d\n", - req->vaddr, req->size); - - Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6; - - switch (req->size) { - - case sizeof(uint64_t): - switch(daddr) { - case TSDEV_PC_WSBA0: - *(uint64_t*)data = wsba[0]; - return NoFault; - case TSDEV_PC_WSBA1: - *(uint64_t*)data = wsba[1]; - return NoFault; - case TSDEV_PC_WSBA2: - *(uint64_t*)data = wsba[2]; - return NoFault; - case TSDEV_PC_WSBA3: - *(uint64_t*)data = wsba[3]; - return NoFault; - case TSDEV_PC_WSM0: - *(uint64_t*)data = wsm[0]; - return NoFault; - case TSDEV_PC_WSM1: - *(uint64_t*)data = wsm[1]; - return NoFault; - case TSDEV_PC_WSM2: - *(uint64_t*)data = wsm[2]; - return NoFault; - case TSDEV_PC_WSM3: - *(uint64_t*)data = wsm[3]; - return NoFault; - case TSDEV_PC_TBA0: - *(uint64_t*)data = tba[0]; - return NoFault; - case TSDEV_PC_TBA1: - *(uint64_t*)data = tba[1]; - return NoFault; - case TSDEV_PC_TBA2: - *(uint64_t*)data = tba[2]; - return NoFault; - case TSDEV_PC_TBA3: - *(uint64_t*)data = tba[3]; - return NoFault; - case TSDEV_PC_PCTL: - *(uint64_t*)data = pctl; - return NoFault; - case TSDEV_PC_PLAT: - panic("PC_PLAT not implemented\n"); - case TSDEV_PC_RES: - panic("PC_RES not implemented\n"); - case TSDEV_PC_PERROR: - *(uint64_t*)data = 0x00; - return NoFault; - case TSDEV_PC_PERRMASK: - *(uint64_t*)data = 0x00; - return NoFault; - case TSDEV_PC_PERRSET: - panic("PC_PERRSET not implemented\n"); - case TSDEV_PC_TLBIV: - panic("PC_TLBIV not implemented\n"); - case TSDEV_PC_TLBIA: - *(uint64_t*)data = 0x00; // shouldn't be readable, but linux - return NoFault; - case TSDEV_PC_PMONCTL: - panic("PC_PMONCTL not implemented\n"); - case TSDEV_PC_PMONCNT: - panic("PC_PMONCTN not implemented\n"); - default: - panic("Default in PChip Read reached reading 0x%x\n", daddr); - - } // uint64_t - - break; - case sizeof(uint32_t): - case sizeof(uint16_t): - case sizeof(uint8_t): + assert(pkt.result == Unknown); + assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); + + + pkt.time += pioDelay; + pkt.allocate(); + Addr daddr = (pkt.addr - pioAddr) >> 6;; + assert(pkt.size == sizeof(uint64_t)); + + + DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt.addr, pkt.size); + + switch(daddr) { + case TSDEV_PC_WSBA0: + pkt.set(wsba[0]); + break; + case TSDEV_PC_WSBA1: + pkt.set(wsba[1]); + break; + case TSDEV_PC_WSBA2: + pkt.set(wsba[2]); + break; + case TSDEV_PC_WSBA3: + pkt.set(wsba[3]); + break; + case TSDEV_PC_WSM0: + pkt.set(wsm[0]); + break; + case TSDEV_PC_WSM1: + pkt.set(wsm[1]); + break; + case TSDEV_PC_WSM2: + pkt.set(wsm[2]); + break; + case TSDEV_PC_WSM3: + pkt.set(wsm[3]); + break; + case TSDEV_PC_TBA0: + pkt.set(tba[0]); + break; + case TSDEV_PC_TBA1: + pkt.set(tba[1]); + break; + case TSDEV_PC_TBA2: + pkt.set(tba[2]); + break; + case TSDEV_PC_TBA3: + pkt.set(tba[3]); + break; + case TSDEV_PC_PCTL: + pkt.set(pctl); + break; + case TSDEV_PC_PLAT: + panic("PC_PLAT not implemented\n"); + case TSDEV_PC_RES: + panic("PC_RES not implemented\n"); + case TSDEV_PC_PERROR: + pkt.set((uint64_t)0x00); + break; + case TSDEV_PC_PERRMASK: + pkt.set((uint64_t)0x00); + break; + case TSDEV_PC_PERRSET: + panic("PC_PERRSET not implemented\n"); + case TSDEV_PC_TLBIV: + panic("PC_TLBIV not implemented\n"); + case TSDEV_PC_TLBIA: + pkt.set((uint64_t)0x00); // shouldn't be readable, but linux + break; + case TSDEV_PC_PMONCTL: + panic("PC_PMONCTL not implemented\n"); + case TSDEV_PC_PMONCNT: + panic("PC_PMONCTN not implemented\n"); default: - panic("invalid access size(?) for tsunami register!\n\n"); + panic("Default in PChip Read reached reading 0x%x\n", daddr); } - DPRINTFN("Tsunami PChip ERROR: read daddr=%#x size=%d\n", daddr, req->size); + pkt.result = Success; + return pioDelay; - return NoFault; } -Fault -TsunamiPChip::write(MemReqPtr &req, const uint8_t *data) +Tick +TsunamiPChip::write(Packet &pkt) { - DPRINTF(Tsunami, "write - va=%#x size=%d \n", - req->vaddr, req->size); - - Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6; - - switch (req->size) { - - case sizeof(uint64_t): - switch(daddr) { - case TSDEV_PC_WSBA0: - wsba[0] = *(uint64_t*)data; - return NoFault; - case TSDEV_PC_WSBA1: - wsba[1] = *(uint64_t*)data; - return NoFault; - case TSDEV_PC_WSBA2: - wsba[2] = *(uint64_t*)data; - return NoFault; - case TSDEV_PC_WSBA3: - wsba[3] = *(uint64_t*)data; - return NoFault; - case TSDEV_PC_WSM0: - wsm[0] = *(uint64_t*)data; - return NoFault; - case TSDEV_PC_WSM1: - wsm[1] = *(uint64_t*)data; - return NoFault; - case TSDEV_PC_WSM2: - wsm[2] = *(uint64_t*)data; - return NoFault; - case TSDEV_PC_WSM3: - wsm[3] = *(uint64_t*)data; - return NoFault; - case TSDEV_PC_TBA0: - tba[0] = *(uint64_t*)data; - return NoFault; - case TSDEV_PC_TBA1: - tba[1] = *(uint64_t*)data; - return NoFault; - case TSDEV_PC_TBA2: - tba[2] = *(uint64_t*)data; - return NoFault; - case TSDEV_PC_TBA3: - tba[3] = *(uint64_t*)data; - return NoFault; - case TSDEV_PC_PCTL: - pctl = *(uint64_t*)data; - return NoFault; - case TSDEV_PC_PLAT: - panic("PC_PLAT not implemented\n"); - case TSDEV_PC_RES: - panic("PC_RES not implemented\n"); - case TSDEV_PC_PERROR: - return NoFault; - case TSDEV_PC_PERRMASK: - panic("PC_PERRMASK not implemented\n"); - case TSDEV_PC_PERRSET: - panic("PC_PERRSET not implemented\n"); - case TSDEV_PC_TLBIV: - panic("PC_TLBIV not implemented\n"); - case TSDEV_PC_TLBIA: - return NoFault; // value ignored, supposted to invalidate SG TLB - case TSDEV_PC_PMONCTL: - panic("PC_PMONCTL not implemented\n"); - case TSDEV_PC_PMONCNT: - panic("PC_PMONCTN not implemented\n"); - default: - panic("Default in PChip Read reached reading 0x%x\n", daddr); - - } // uint64_t - - break; - case sizeof(uint32_t): - case sizeof(uint16_t): - case sizeof(uint8_t): - default: - panic("invalid access size(?) for tsunami register!\n\n"); - } - - DPRINTFN("Tsunami ERROR: write daddr=%#x size=%d\n", daddr, req->size); - - return NoFault; + pkt.time += pioDelay; + + assert(pkt.result == Unknown); + assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); + Addr daddr = (pkt.addr - pioAddr) >> 6; + + assert(pkt.size == sizeof(uint64_t)); + + DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt.addr, pkt.size); + + switch(daddr) { + case TSDEV_PC_WSBA0: + wsba[0] = pkt.get<uint64_t>(); + break; + case TSDEV_PC_WSBA1: + wsba[1] = pkt.get<uint64_t>(); + break; + case TSDEV_PC_WSBA2: + wsba[2] = pkt.get<uint64_t>(); + break; + case TSDEV_PC_WSBA3: + wsba[3] = pkt.get<uint64_t>(); + break; + case TSDEV_PC_WSM0: + wsm[0] = pkt.get<uint64_t>(); + break; + case TSDEV_PC_WSM1: + wsm[1] = pkt.get<uint64_t>(); + break; + case TSDEV_PC_WSM2: + wsm[2] = pkt.get<uint64_t>(); + break; + case TSDEV_PC_WSM3: + wsm[3] = pkt.get<uint64_t>(); + break; + case TSDEV_PC_TBA0: + tba[0] = pkt.get<uint64_t>(); + break; + case TSDEV_PC_TBA1: + tba[1] = pkt.get<uint64_t>(); + break; + case TSDEV_PC_TBA2: + tba[2] = pkt.get<uint64_t>(); + break; + case TSDEV_PC_TBA3: + tba[3] = pkt.get<uint64_t>(); + break; + case TSDEV_PC_PCTL: + pctl = pkt.get<uint64_t>(); + break; + case TSDEV_PC_PLAT: + panic("PC_PLAT not implemented\n"); + case TSDEV_PC_RES: + panic("PC_RES not implemented\n"); + case TSDEV_PC_PERROR: + break; + case TSDEV_PC_PERRMASK: + panic("PC_PERRMASK not implemented\n"); + case TSDEV_PC_PERRSET: + panic("PC_PERRSET not implemented\n"); + case TSDEV_PC_TLBIV: + panic("PC_TLBIV not implemented\n"); + case TSDEV_PC_TLBIA: + break; // value ignored, supposted to invalidate SG TLB + case TSDEV_PC_PMONCTL: + panic("PC_PMONCTL not implemented\n"); + case TSDEV_PC_PMONCNT: + panic("PC_PMONCTN not implemented\n"); + default: + panic("Default in PChip write reached reading 0x%x\n", daddr); + + } // uint64_t + + pkt.result = Success; + return pioDelay; } #define DMA_ADDR_MASK ULL(0x3ffffffff) @@ -311,10 +285,7 @@ TsunamiPChip::translatePciToDma(Addr busAddr) baMask = (wsm[i] & (ULL(0xfff) << 20)) | (ULL(0x7f) << 13); pteAddr = (tba[i] & tbaMask) | ((busAddr & baMask) >> 10); - memcpy((void *)&pteEntry, - tsunami->system-> - physmem->dma_addr(pteAddr, sizeof(uint64_t)), - sizeof(uint64_t)); + pioPort->readBlob(pteAddr, (uint8_t*)&pteEntry, sizeof(uint64_t)); dmaAddr = ((pteEntry & ~ULL(0x1)) << 12) | (busAddr & ULL(0x1fff)); @@ -351,38 +322,37 @@ TsunamiPChip::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_ARRAY(tba, 4); } -Tick -TsunamiPChip::cacheAccess(MemReqPtr &req) -{ - return curTick + pioLatency; -} BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip) - SimObjectParam<Tsunami *> tsunami; - SimObjectParam<MemoryController *> mmu; - Param<Addr> addr; - SimObjectParam<Bus*> pio_bus; + Param<Addr> pio_addr; Param<Tick> pio_latency; - SimObjectParam<HierParams *> hier; + SimObjectParam<Platform *> platform; + SimObjectParam<System *> system; + SimObjectParam<Tsunami *> tsunami; END_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip) BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiPChip) - INIT_PARAM(tsunami, "Tsunami"), - INIT_PARAM(mmu, "Memory Controller"), - INIT_PARAM(addr, "Device Address"), - INIT_PARAM_DFLT(pio_bus, "The IO Bus to attach to", NULL), - INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1), - INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) + INIT_PARAM(pio_addr, "Device Address"), + INIT_PARAM(pio_latency, "Programmed IO latency"), + INIT_PARAM(platform, "platform"), + INIT_PARAM(system, "system object"), + INIT_PARAM(tsunami, "Tsunami") END_INIT_SIM_OBJECT_PARAMS(TsunamiPChip) CREATE_SIM_OBJECT(TsunamiPChip) { - return new TsunamiPChip(getInstanceName(), tsunami, addr, mmu, hier, - pio_bus, pio_latency); + TsunamiPChip::Params *p = new TsunamiPChip::Params; + p->name = getInstanceName(); + p->pio_addr = pio_addr; + p->pio_delay = pio_latency; + p->platform = platform; + p->system = system; + p->tsunami = tsunami; + return new TsunamiPChip(p); } REGISTER_SIM_OBJECT("TsunamiPChip", TsunamiPChip) diff --git a/dev/tsunami_pchip.hh b/dev/tsunami_pchip.hh index c1d95431b..2f3e8f078 100644 --- a/dev/tsunami_pchip.hh +++ b/dev/tsunami_pchip.hh @@ -37,28 +37,12 @@ #include "base/range.hh" #include "dev/io_device.hh" -class MemoryController; - /** * A very simple implementation of the Tsunami PCI interface chips. */ -class TsunamiPChip : public PioDevice +class TsunamiPChip : public BasicPioDevice { - private: - /** The base address of this device */ - Addr addr; - - /** The size of mappad from the above address */ - static const Addr size = 0xfff; - protected: - /** - * pointer to the tsunami object. - * This is our access to all the other tsunami - * devices. - */ - Tsunami *tsunami; - /** Pchip control register */ uint64_t pctl; @@ -72,18 +56,19 @@ class TsunamiPChip : public PioDevice uint64_t tba[4]; public: + struct Params : public BasicPioDevice::Params + { + Tsunami *tsunami; + }; + protected: + const Params *params() const { return (const Params*)_params; } + + public: /** * Register the PChip with the mmu and init all wsba, wsm, and tba to 0 - * @param name the name of thes device - * @param t a pointer to the tsunami device - * @param a the address which we respond to - * @param mmu the mmu we are to register with - * @param hier object to store parameters universal the device hierarchy - * @param bus The bus that this device is attached to + * @param p pointer to the parameters struct */ - TsunamiPChip(const std::string &name, Tsunami *t, Addr a, - MemoryController *mmu, HierParams *hier, Bus *pio_bus, - Tick pio_latency); + TsunamiPChip(Params *p); /** * Translate a PCI bus address to a memory address for DMA. @@ -93,21 +78,8 @@ class TsunamiPChip : public PioDevice */ Addr translatePciToDma(Addr busAddr); - /** - * Process a read to the PChip. - * @param req Contains the address to read from. - * @param data A pointer to write the read data to. - * @return The fault condition of the access. - */ - virtual Fault read(MemReqPtr &req, uint8_t *data); - - /** - * Process a write to the PChip. - * @param req Contains the address to write to. - * @param data The data to write. - * @return The fault condition of the access. - */ - virtual Fault write(MemReqPtr &req, const uint8_t *data); + virtual Tick read(Packet &pkt); + virtual Tick write(Packet &pkt); /** * Serialize this object to the given output stream. @@ -121,13 +93,6 @@ class TsunamiPChip : public PioDevice * @param section The section name of this object */ virtual void unserialize(Checkpoint *cp, const std::string §ion); - - /** - * Return how long this access will take. - * @param req the memory request to calcuate - * @return Tick when the request is done - */ - Tick cacheAccess(MemReqPtr &req); }; #endif // __TSUNAMI_PCHIP_HH__ diff --git a/dev/uart.cc b/dev/uart.cc index b2eeb8e9f..4a9f2b505 100644 --- a/dev/uart.cc +++ b/dev/uart.cc @@ -27,39 +27,19 @@ */ /** @file - * Implements a 8250 UART + * Implements a base class for UARTs */ -#include <string> -#include <vector> - -#include "base/inifile.hh" -#include "base/str.hh" // for to_number -#include "base/trace.hh" #include "dev/simconsole.hh" #include "dev/uart.hh" #include "dev/platform.hh" -#include "mem/bus/bus.hh" -#include "mem/bus/pio_interface.hh" -#include "mem/bus/pio_interface_impl.hh" -#include "mem/functional/memory_control.hh" #include "sim/builder.hh" using namespace std; -Uart::Uart(const string &name, SimConsole *c, MemoryController *mmu, Addr a, - Addr s, HierParams *hier, Bus *bus, Tick pio_latency, Platform *p) - : PioDevice(name, p), addr(a), size(s), cons(c) +Uart::Uart(Params *p) + : BasicPioDevice(p), platform(p->platform), cons(p->cons) { - mmu->add_child(this, RangeSize(addr, size)); - - - if (bus) { - pioInterface = newPioInterface(name, hier, bus, this, - &Uart::cacheAccess); - pioInterface->addAddrRange(RangeSize(addr, size)); - pioLatency = pio_latency * bus->clockRate; - } status = 0; @@ -68,11 +48,5 @@ Uart::Uart(const string &name, SimConsole *c, MemoryController *mmu, Addr a, platform->uart = this; } -Tick -Uart::cacheAccess(MemReqPtr &req) -{ - return curTick + pioLatency; -} - DEFINE_SIM_OBJECT_CLASS_NAME("Uart", Uart) diff --git a/dev/uart.hh b/dev/uart.hh index 78b1dc68e..2dd15d9b8 100644 --- a/dev/uart.hh +++ b/dev/uart.hh @@ -37,30 +37,27 @@ #include "dev/io_device.hh" class SimConsole; -class MemoryController; class Platform; const int RX_INT = 0x1; const int TX_INT = 0x2; -class Uart : public PioDevice +class Uart : public BasicPioDevice { protected: int status; - Addr addr; - Addr size; + Platform *platform; SimConsole *cons; public: - Uart(const std::string &name, SimConsole *c, MemoryController *mmu, - Addr a, Addr s, HierParams *hier, Bus *bus, Tick pio_latency, - Platform *p); - - virtual Fault read(MemReqPtr &req, uint8_t *data) = 0; - virtual Fault write(MemReqPtr &req, const uint8_t *data) = 0; + struct Params : public BasicPioDevice::Params + { + SimConsole *cons; + }; + Uart(Params *p); /** * Inform the uart that there is data available. @@ -74,12 +71,9 @@ class Uart : public PioDevice */ bool intStatus() { return status ? true : false; } - /** - * Return how long this access will take. - * @param req the memory request to calcuate - * @return Tick when the request is done - */ - Tick cacheAccess(MemReqPtr &req); + protected: + const Params *params() const {return (const Params *)_params; } + }; #endif // __UART_HH__ diff --git a/dev/uart8250.cc b/dev/uart8250.cc index 65bccee86..15752c735 100644 --- a/dev/uart8250.cc +++ b/dev/uart8250.cc @@ -33,16 +33,13 @@ #include <string> #include <vector> +#include "arch/alpha/ev5.hh" #include "base/inifile.hh" #include "base/str.hh" // for to_number #include "base/trace.hh" #include "dev/simconsole.hh" #include "dev/uart8250.hh" #include "dev/platform.hh" -#include "mem/bus/bus.hh" -#include "mem/bus/pio_interface.hh" -#include "mem/bus/pio_interface_impl.hh" -#include "mem/functional/memory_control.hh" #include "sim/builder.hh" using namespace std; @@ -99,34 +96,37 @@ Uart8250::IntrEvent::scheduleIntr() } -Uart8250::Uart8250(const string &name, SimConsole *c, MemoryController *mmu, - Addr a, Addr s, HierParams *hier, Bus *pio_bus, - Tick pio_latency, Platform *p) - : Uart(name, c, mmu, a, s, hier, pio_bus, pio_latency, p), - txIntrEvent(this, TX_INT), rxIntrEvent(this, RX_INT) +Uart8250::Uart8250(Params *p) + : Uart(p), txIntrEvent(this, TX_INT), rxIntrEvent(this, RX_INT) { + pioSize = 8; + IER = 0; DLAB = 0; LCR = 0; MCR = 0; - } -Fault -Uart8250::read(MemReqPtr &req, uint8_t *data) +Tick +Uart8250::read(Packet &pkt) { - Addr daddr = req->paddr - (addr & EV5::PAddrImplMask); - DPRINTF(Uart, " read register %#x\n", daddr); + assert(pkt.result == Unknown); + assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); + assert(pkt.size == 1); - assert(req->size == 1); + pkt.time += pioDelay; + Addr daddr = pkt.addr - pioAddr; + pkt.allocate(); + + DPRINTF(Uart, " read register %#x\n", daddr); switch (daddr) { case 0x0: if (!(LCR & 0x80)) { // read byte if (cons->dataAvailable()) - cons->in(*data); + cons->in(*pkt.getPtr<uint8_t>()); else { - *(uint8_t*)data = 0; + pkt.set((uint8_t)0); // A limited amount of these are ok. DPRINTF(Uart, "empty read of RX register\n"); } @@ -141,7 +141,7 @@ Uart8250::read(MemReqPtr &req, uint8_t *data) break; case 0x1: if (!(LCR & 0x80)) { // Intr Enable Register(IER) - *(uint8_t*)data = IER; + pkt.set(IER); } else { // DLM divisor latch MSB ; } @@ -150,17 +150,17 @@ Uart8250::read(MemReqPtr &req, uint8_t *data) DPRINTF(Uart, "IIR Read, status = %#x\n", (uint32_t)status); if (status & RX_INT) /* Rx data interrupt has a higher priority */ - *(uint8_t*)data = IIR_RXID; + pkt.set(IIR_RXID); else if (status & TX_INT) - *(uint8_t*)data = IIR_TXID; + pkt.set(IIR_TXID); else - *(uint8_t*)data = IIR_NOPEND; + pkt.set(IIR_NOPEND); //Tx interrupts are cleared on IIR reads status &= ~TX_INT; break; case 0x3: // Line Control Register (LCR) - *(uint8_t*)data = LCR; + pkt.set(LCR); break; case 0x4: // Modem Control Register (MCR) break; @@ -171,34 +171,42 @@ Uart8250::read(MemReqPtr &req, uint8_t *data) if (cons->dataAvailable()) lsr = UART_LSR_DR; lsr |= UART_LSR_TEMT | UART_LSR_THRE; - *(uint8_t*)data = lsr; + pkt.set(lsr); break; case 0x6: // Modem Status Register (MSR) - *(uint8_t*)data = 0; + pkt.set((uint8_t)0); break; case 0x7: // Scratch Register (SCR) - *(uint8_t*)data = 0; // doesn't exist with at 8250. + pkt.set((uint8_t)0); // doesn't exist with at 8250. break; default: panic("Tried to access a UART port that doesn't exist\n"); break; } - - return NoFault; - +/* uint32_t d32 = *data; + DPRINTF(Uart, "Register read to register %#x returned %#x\n", daddr, d32); +*/ + pkt.result = Success; + return pioDelay; } -Fault -Uart8250::write(MemReqPtr &req, const uint8_t *data) +Tick +Uart8250::write(Packet &pkt) { - Addr daddr = req->paddr - (addr & EV5::PAddrImplMask); - DPRINTF(Uart, " write register %#x value %#x\n", daddr, *(uint8_t*)data); + assert(pkt.result == Unknown); + assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); + assert(pkt.size == 1); + + pkt.time += pioDelay; + Addr daddr = pkt.addr - pioAddr; + + DPRINTF(Uart, " write register %#x value %#x\n", daddr, pkt.get<uint8_t>()); switch (daddr) { case 0x0: if (!(LCR & 0x80)) { // write byte - cons->out(*(uint8_t *)data); + cons->out(pkt.get<uint8_t>()); platform->clearConsoleInt(); status &= ~TX_INT; if (UART_IER_THRI & IER) @@ -209,7 +217,7 @@ Uart8250::write(MemReqPtr &req, const uint8_t *data) break; case 0x1: if (!(LCR & 0x80)) { // Intr Enable Register(IER) - IER = *(uint8_t*)data; + IER = pkt.get<uint8_t>(); if (UART_IER_THRI & IER) { DPRINTF(Uart, "IER: IER_THRI set, scheduling TX intrrupt\n"); @@ -243,10 +251,10 @@ Uart8250::write(MemReqPtr &req, const uint8_t *data) case 0x2: // FIFO Control Register (FCR) break; case 0x3: // Line Control Register (LCR) - LCR = *(uint8_t*)data; + LCR = pkt.get<uint8_t>(); break; case 0x4: // Modem Control Register (MCR) - if (*(uint8_t*)data == (UART_MCR_LOOP | 0x0A)) + if (pkt.get<uint8_t>() == (UART_MCR_LOOP | 0x0A)) MCR = 0x9A; break; case 0x7: // Scratch Register (SCR) @@ -256,7 +264,8 @@ Uart8250::write(MemReqPtr &req, const uint8_t *data) panic("Tried to access a UART port that doesn't exist\n"); break; } - return NoFault; + pkt.result = Success; + return pioDelay; } void @@ -271,6 +280,14 @@ Uart8250::dataAvailable() } +void +Uart8250::addressRanges(AddrRangeList &range_list) +{ + assert(pioSize != 0); + range_list.clear(); + range_list.push_back(RangeSize(pioAddr, pioSize)); +} + void @@ -315,35 +332,35 @@ Uart8250::unserialize(Checkpoint *cp, const std::string §ion) BEGIN_DECLARE_SIM_OBJECT_PARAMS(Uart8250) - SimObjectParam<SimConsole *> console; - SimObjectParam<MemoryController *> mmu; - SimObjectParam<Platform *> platform; - Param<Addr> addr; - Param<Addr> size; - SimObjectParam<Bus*> pio_bus; + Param<Addr> pio_addr; Param<Tick> pio_latency; - SimObjectParam<HierParams *> hier; - + SimObjectParam<Platform *> platform; + SimObjectParam<SimConsole *> sim_console; + SimObjectParam<System *> system; END_DECLARE_SIM_OBJECT_PARAMS(Uart8250) BEGIN_INIT_SIM_OBJECT_PARAMS(Uart8250) - INIT_PARAM(console, "The console"), - INIT_PARAM(mmu, "Memory Controller"), - INIT_PARAM(platform, "Pointer to platfrom"), - INIT_PARAM(addr, "Device Address"), - INIT_PARAM_DFLT(size, "Device size", 0x8), - INIT_PARAM(pio_bus, ""), - INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1), - INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) + INIT_PARAM(pio_addr, "Device Address"), + INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000), + INIT_PARAM(platform, "platform"), + INIT_PARAM(sim_console, "The Simulator Console"), + INIT_PARAM(system, "system object") END_INIT_SIM_OBJECT_PARAMS(Uart8250) CREATE_SIM_OBJECT(Uart8250) { - return new Uart8250(getInstanceName(), console, mmu, addr, size, hier, - pio_bus, pio_latency, platform); + Uart8250::Params *p = new Uart8250::Params; + p->name = getInstanceName(); + p->pio_addr = pio_addr; + p->pio_delay = pio_latency; + p->platform = platform; + p->cons = sim_console; + p->system = system; + return new Uart8250(p); } REGISTER_SIM_OBJECT("Uart8250", Uart8250) + diff --git a/dev/uart8250.hh b/dev/uart8250.hh index 63d1da3cf..19e4438bc 100644 --- a/dev/uart8250.hh +++ b/dev/uart8250.hh @@ -30,8 +30,8 @@ * Defines a 8250 UART */ -#ifndef __TSUNAMI_UART_HH__ -#define __TSUNAMI_UART_HH__ +#ifndef __DEV_UART8250_HH__ +#define __DEV_UART8250_HH__ #include "dev/tsunamireg.h" #include "base/range.hh" @@ -44,16 +44,15 @@ * bit 2:1 ID of highest priority interrupt * bit 7:3 zeroes */ -#define IIR_NOPEND 0x1 +const uint8_t IIR_NOPEND = 0x1; // Interrupt IDs -#define IIR_MODEM 0x00 /* Modem Status (lowest priority) */ -#define IIR_TXID 0x02 /* Tx Data */ -#define IIR_RXID 0x04 /* Rx Data */ -#define IIR_LINE 0x06 /* Rx Line Status (highest priority)*/ +const uint8_t IIR_MODEM = 0x00; /* Modem Status (lowest priority) */ +const uint8_t IIR_TXID = 0x02; /* Tx Data */ +const uint8_t IIR_RXID = 0x04; /* Rx Data */ +const uint8_t IIR_LINE = 0x06; /* Rx Line Status (highest priority)*/ class SimConsole; -class MemoryController; class Platform; class Uart8250 : public Uart @@ -79,12 +78,11 @@ class Uart8250 : public Uart IntrEvent rxIntrEvent; public: - Uart8250(const std::string &name, SimConsole *c, MemoryController *mmu, - Addr a, Addr s, HierParams *hier, Bus *pio_bus, Tick pio_latency, - Platform *p); + Uart8250(Params *p); - virtual Fault read(MemReqPtr &req, uint8_t *data); - virtual Fault write(MemReqPtr &req, const uint8_t *data); + virtual Tick read(Packet &pkt); + virtual Tick write(Packet &pkt); + virtual void addressRanges(AddrRangeList &range_list); /** |