diff options
Diffstat (limited to 'dev')
-rw-r--r-- | dev/alpha_console.cc | 182 | ||||
-rw-r--r-- | dev/alpha_console.hh | 31 | ||||
-rw-r--r-- | dev/io_device.cc | 125 | ||||
-rw-r--r-- | dev/io_device.hh | 198 | ||||
-rw-r--r-- | dev/simconsole.cc | 1 | ||||
-rw-r--r-- | dev/simple_disk.cc | 22 | ||||
-rw-r--r-- | dev/simple_disk.hh | 6 | ||||
-rw-r--r-- | dev/tsunami_cchip.cc | 144 | ||||
-rw-r--r-- | dev/tsunami_cchip.hh | 52 | ||||
-rw-r--r-- | dev/uart.cc | 32 | ||||
-rw-r--r-- | dev/uart.hh | 26 | ||||
-rw-r--r-- | dev/uart8250.cc | 120 | ||||
-rw-r--r-- | dev/uart8250.hh | 14 |
13 files changed, 539 insertions, 414 deletions
diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc index f40c5b7bf..88219fcbc 100644 --- a/dev/alpha_console.cc +++ b/dev/alpha_console.cc @@ -34,7 +34,6 @@ #include <cstdio> #include <string> -#include "arch/alpha/ev5.hh" #include "arch/alpha/system.hh" #include "base/inifile.hh" #include "base/str.hh" @@ -42,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; @@ -84,7 +72,7 @@ AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d, alphaAccess->inputChar = 0; bzero(alphaAccess->cpuStack, sizeof(alphaAccess->cpuStack)); - system->setAlphaAccess(addr); + system->setAlphaAccess(pioAddr); } void @@ -96,118 +84,140 @@ AlphaConsole::startup() 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(); +} + +void +AlphaConsole::addressRanges(AddrRangeList &range_list) +{ + assert(pioSize != 0); + range_list.clear(); + range_list.push_back(RangeSize(pioAddr, sizeof(struct AlphaAccess))); } -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); + + pkt.time = curTick + pioDelay; + Addr daddr = pkt.addr - pioAddr; - switch (req->size) + uint32_t *data32; + uint64_t *data64; + + switch (pkt.size) { case sizeof(uint32_t): - DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, - *(uint32_t*)data); + if (!pkt.data) { + data32 = new uint32_t; + pkt.data = (uint8_t*)data32; + } else + data32 = (uint32_t*)pkt.data; + switch (daddr) { case offsetof(AlphaAccess, last_offset): - *(uint32_t*)data = alphaAccess->last_offset; + *data32 = alphaAccess->last_offset; break; case offsetof(AlphaAccess, version): - *(uint32_t*)data = alphaAccess->version; + *data32 = alphaAccess->version; break; case offsetof(AlphaAccess, numCPUs): - *(uint32_t*)data = alphaAccess->numCPUs; + *data32 = alphaAccess->numCPUs; break; case offsetof(AlphaAccess, intrClockFrequency): - *(uint32_t*)data = alphaAccess->intrClockFrequency; + *data32 = 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, *data32); break; case sizeof(uint64_t): - DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, - *(uint64_t*)data); + if (!pkt.data) { + data64 = new uint64_t; + pkt.data = (uint8_t*)data64; + } else + data64 = (uint64_t*)pkt.data; switch (daddr) { case offsetof(AlphaAccess, inputChar): - *(uint64_t*)data = console->console_in(); + *data64 = console->console_in(); break; case offsetof(AlphaAccess, cpuClock): - *(uint64_t*)data = alphaAccess->cpuClock; + *data64 = alphaAccess->cpuClock; break; case offsetof(AlphaAccess, mem_size): - *(uint64_t*)data = alphaAccess->mem_size; + *data64 = alphaAccess->mem_size; break; case offsetof(AlphaAccess, kernStart): - *(uint64_t*)data = alphaAccess->kernStart; + *data64 = alphaAccess->kernStart; break; case offsetof(AlphaAccess, kernEnd): - *(uint64_t*)data = alphaAccess->kernEnd; + *data64 = alphaAccess->kernEnd; break; case offsetof(AlphaAccess, entryPoint): - *(uint64_t*)data = alphaAccess->entryPoint; + *data64 = alphaAccess->entryPoint; break; case offsetof(AlphaAccess, diskUnit): - *(uint64_t*)data = alphaAccess->diskUnit; + *data64 = alphaAccess->diskUnit; break; case offsetof(AlphaAccess, diskCount): - *(uint64_t*)data = alphaAccess->diskCount; + *data64 = alphaAccess->diskCount; break; case offsetof(AlphaAccess, diskPAddr): - *(uint64_t*)data = alphaAccess->diskPAddr; + *data64 = alphaAccess->diskPAddr; break; case offsetof(AlphaAccess, diskBlock): - *(uint64_t*)data = alphaAccess->diskBlock; + *data64 = alphaAccess->diskBlock; break; case offsetof(AlphaAccess, diskOperation): - *(uint64_t*)data = alphaAccess->diskOperation; + *data64 = alphaAccess->diskOperation; break; case offsetof(AlphaAccess, outputChar): - *(uint64_t*)data = alphaAccess->outputChar; + *data64 = 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]; + *data64 = alphaAccess->cpuStack[cpunum]; else panic("Unknown 64bit access, %#x\n", daddr); } + DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, *data64); 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 = curTick + 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 = *(uint64_t *)pkt.data; + assert(pkt.size == sizeof(uint64_t)); switch (daddr) { case offsetof(AlphaAccess, diskUnit): @@ -239,9 +249,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]); @@ -253,13 +260,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 @@ -322,14 +325,11 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) SimObjectParam<SimConsole *> sim_console; SimObjectParam<SimpleDisk *> disk; - SimObjectParam<MemoryController *> mmu; Param<Addr> 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) @@ -337,21 +337,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(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 = 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..0435feb89 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,38 @@ 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); + + /** Address ranges this device is sensitive to. */ + virtual void addressRanges(AddrRangeList &range_list); /** * 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/io_device.cc b/dev/io_device.cc index b580c2805..a72944cfc 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 @@ -29,61 +29,110 @@ #include "dev/io_device.hh" #include "sim/builder.hh" + +PioPort::PioPort(PioDevice *dev, Platform *p) + : device(dev), platform(p) +{ } + + +Tick +PioPort::recvAtomic(Packet &pkt) +{ + return device->recvAtomic(pkt); +} + void -PioPort::SendEvent::process() +PioPort::recvFunctional(Packet &pkt) { - if (port->sendTiming(packet) == Success) - return; + device->recvAtomic(pkt); +} - port->transmitList.push_back(&packet); +void +PioPort::getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) +{ + snoop.clear(); + device->addressRanges(resp); } -PioDevice::PioDevice(const std::string &name, Platform *p) - : SimObject(name), platform(p) + +Packet * +PioPort::recvRetry() { - pioPort = new PioPort(this); + 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 -PioDevice::recvTiming(Packet &pkt) +PioPort::recvTiming(Packet &pkt) { device->recvAtomic(pkt); - sendTiming(pkt, pkt.responseTime-pkt.requestTime); + sendTiming(pkt, pkt.time-pkt.req->getTime()); return Success; } PioDevice::~PioDevice() { if (pioPort) - delete pioInterface; + delete pioPort; } -void -DmaPort::sendDma(Packet &pkt) + +DmaPort::DmaPort(DmaDevice *dev) + : device(dev) +{ } + +bool +DmaPort::recvTiming(Packet &pkt) { - device->platform->system->memoryMode() - { - case MemAtomic: - } + completionEvent->schedule(curTick+1); + completionEvent = NULL; + return Success; +} + +DmaDevice::DmaDevice(Params *p) + : PioDevice(p) +{ + dmaPort = new DmaPort(this); } -DmaDevice::DmaDevice(const std::string &name, Platform *p) - : PioDevice(name, p) +void +DmaPort::SendEvent::process() { - dmaPort = new dmaPort(this); + 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(Memory::Command cmd, DmaPort port, Addr addr, int size, - Event *event, uint8_t *data = NULL) +DmaPort::dmaAction(Command cmd, DmaPort port, Addr addr, int size, + Event *event, uint8_t *data) { assert(event); int prevSize = 0; Packet basePkt; - Request baseReq; + Request baseReq(false); basePkt.flags = 0; basePkt.coherence = NULL; @@ -92,9 +141,9 @@ DmaPort::dmaAction(Memory::Command cmd, DmaPort port, Addr addr, int size, basePkt.dest = 0; basePkt.cmd = cmd; basePkt.result = Unknown; - basePkt.request = NULL; - baseReq.nicReq = true; - baseReq.time = curTick; + basePkt.req = NULL; +// baseReq.nicReq = true; + baseReq.setTime(curTick); completionEvent = event; @@ -105,11 +154,11 @@ DmaPort::dmaAction(Memory::Command cmd, DmaPort port, Addr addr, int size, pkt->addr = gen.addr(); pkt->size = gen.size(); pkt->req = req; - pkt->req->paddr = pkt->addr; - pkt->req->size = pkt->size; + pkt->req->setPaddr(pkt->addr); + pkt->req->setSize(pkt->size); // Increment the data pointer on a write pkt->data = data ? data + prevSize : NULL ; - prevSize = pkt->size; + prevSize += pkt->size; sendDma(*pkt); } @@ -122,29 +171,29 @@ 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; + /* MemState state = device->platform->system->memState; if (state == Timing) { if (sendTiming(pkt) == Failure) transmitList.push_back(&packet); - } else if (state == Atomic) { + } else if (state == Atomic) {*/ sendAtomic(pkt); - completionEvent->schedule(pkt.responseTime - pkt.requestTime); - completionEvent == NULL; - } else if (state == Functional) { + completionEvent->schedule(pkt.time - pkt.req->getTime()); + completionEvent = NULL; +/* } else if (state == Functional) { sendFunctional(pkt); // Is this correct??? - completionEvent->schedule(pkt.responseTime - pkt.requestTime); + 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; } diff --git a/dev/io_device.hh b/dev/io_device.hh index a79c3f20a..a43527b37 100644 --- a/dev/io_device.hh +++ b/dev/io_device.hh @@ -32,30 +32,57 @@ #include "base/chunk_generator.hh" #include "mem/port.hh" #include "sim/eventq.hh" +#include "sim/sim_object.hh" -class Bus; class Platform; class PioDevice; - +class DmaDevice; +class System; + +/** + * 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) - { return device->recvAtomic(pkt) }; + virtual Tick recvAtomic(Packet &pkt); - virtual void recvFunctional(Packet &pkt) - { device->recvAtomic(pkt) }; + virtual void recvFunctional(Packet &pkt) ; - virtual void getDeviceAddressRanges(AddrRangeList &range_list, bool &owner) - { device->addressRanges(range_list, owner); } + virtual void recvStatusChange(Status status) + { peerStatus = status; } - void sendTiming(Packet &pkt, Tick time) - { new SendEvent(this, pkt, time); } + 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; @@ -71,13 +98,19 @@ class PioPort : public Port { 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) - : device(dev) - { } + PioPort(PioDevice *dev, Platform *p); + friend class PioPort::SendEvent; }; class DmaPort : public Port @@ -85,10 +118,10 @@ class DmaPort : public Port protected: PioDevice *device; std::list<Packet*> transmitList; + Event *completionEvent; - virtual bool recvTiming(Packet &pkt) - { completionEvent->schedule(curTick+1); completionEvent = NULL; } + 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) @@ -97,23 +130,14 @@ class DmaPort : public Port virtual void recvStatusChange(Status status) { ; } - virtual Packet *recvRetry() - { return transmitList.pop_front(); } - - virtual void getDeviceAddressRanges(AddrRangeList &range_list, bool &owner) - { range_list.clear(); owner = true; } - - void dmaAction(Memory::Command cmd, DmaPort port, Addr addr, int size, - Event *event, uint8_t *data = NULL); - - void sendDma(Packet &pkt); + virtual Packet *recvRetry() ; - virtual Packet *recvRetry() - { return transmitList.pop_front(); } + virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) + { resp.clear(); snoop.clear(); } class SendEvent : public Event { - PioPort *port; + DmaPort *port; Packet packet; SendEvent(PioPort *p, Packet &pkt, Tick t) @@ -125,46 +149,124 @@ class DmaPort : public Port virtual const char *description() { return "Future scheduled sendTiming event"; } - friend class PioPort; - } + friend class DmaPort; + }; + + void dmaAction(Command cmd, DmaPort port, Addr addr, int size, + Event *event, uint8_t *data = NULL); + + void sendDma(Packet &pkt); + public: - DmaPort(DmaDevice *dev) - : device(dev) - { } + DmaPort(DmaDevice *dev); + 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 SimObject { 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, bool &owner) = 0; + virtual void addressRanges(AddrRangeList &range_list) = 0; - virtual read(Packet &pkt) = 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; - virtual 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. */ - Tick recvAtomic(Packet &pkt) - { return pkt->cmd == Read ? this->read(pkt) : this->write(pkt); } + struct Params + { + std::string name; + Platform *platform; + System *system; + }; + + protected: + Params *_params; public: - PioDevice(const std::string &name, Platform *p); + const Params *params() const { return _params; } + + PioDevice(Params *p) + : SimObject(params()->name), platform(p->platform), _params(p) + {} virtual ~PioDevice(); - virtual Port *getPort(std::string if_name) + virtual Port *getPort(const std::string &if_name) { - if (if_name == "pio") + if (if_name == "pio") { + if (pioPort != NULL) + panic("pio port already connected to."); + pioPort = new PioPort(this, params()->platform); return pioPort; - else + } 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) + {} + }; class DmaDevice : public PioDevice @@ -173,21 +275,21 @@ class DmaDevice : public PioDevice DmaPort *dmaPort; public: - DmaDevice(const std::string &name, Platform *p); + DmaDevice(Params *p); virtual ~DmaDevice(); - virtual Port *getPort(std::string if_name) + virtual Port *getPort(const std::string &if_name) { if (if_name == "pio") return pioPort; - else if (if_name = "dma") + else if (if_name == "dma") return dmaPort; else return NULL; } -}; - + friend class DmaPort; +}; #endif // __DEV_IO_DEVICE_HH__ 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/tsunami_cchip.cc b/dev/tsunami_cchip.cc index 8c6db8a43..f05b6b43e 100644 --- a/dev/tsunami_cchip.cc +++ b/dev/tsunami_cchip.cc @@ -39,10 +39,7 @@ #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" @@ -52,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; @@ -80,123 +68,137 @@ 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); - 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 = curTick + pioDelay; + Addr regnum = (req->paddr - pioAddr) >> 6; + Addr daddr = (req->paddr - pioAddr); - switch (req->size) { + uint32_t *data32; + uint64_t *data64; + + switch (pkt.size) { case sizeof(uint64_t): + if (!pkt.data) { + data64 = new uint64_t; + pkt.data = (uint8_t*)data64; + } else + data64 = (uint64_t*)pkt.data; + if (daddr & TSDEV_CC_BDIMS) { - *(uint64_t*)data = dim[(daddr >> 4) & 0x3F]; - return NoFault; + *data64 = dim[(daddr >> 4) & 0x3F]; + break; } if (daddr & TSDEV_CC_BDIRS) { - *(uint64_t*)data = dir[(daddr >> 4) & 0x3F]; - return NoFault; + *data64 = dir[(daddr >> 4) & 0x3F]; + break; } switch(regnum) { case TSDEV_CC_CSR: - *(uint64_t*)data = 0x0; - return NoFault; + *data64 = 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; + *data64 = (ipint << 8) & 0xF | (itint << 4) & 0xF | + (pkt.req->cpuId & 0x3); + break; case TSDEV_CC_AAR0: case TSDEV_CC_AAR1: case TSDEV_CC_AAR2: case TSDEV_CC_AAR3: - *(uint64_t*)data = 0; - return NoFault; + *data64 = 0; + break; case TSDEV_CC_DIM0: - *(uint64_t*)data = dim[0]; - return NoFault; + *data64 = dim[0]; + break; case TSDEV_CC_DIM1: - *(uint64_t*)data = dim[1]; - return NoFault; + *data64 = dim[1]; + break; case TSDEV_CC_DIM2: - *(uint64_t*)data = dim[2]; - return NoFault; + *data64 = dim[2]; + break; case TSDEV_CC_DIM3: - *(uint64_t*)data = dim[3]; - return NoFault; + *data64 = dim[3]; + break; case TSDEV_CC_DIR0: - *(uint64_t*)data = dir[0]; - return NoFault; + *data64 = dir[0]; + break; case TSDEV_CC_DIR1: - *(uint64_t*)data = dir[1]; - return NoFault; + *data64 = dir[1]; + break; case TSDEV_CC_DIR2: - *(uint64_t*)data = dir[2]; - return NoFault; + *data64 = dir[2]; + break; case TSDEV_CC_DIR3: - *(uint64_t*)data = dir[3]; - return NoFault; + *data64 = dir[3]; + break; case TSDEV_CC_DRIR: - *(uint64_t*)data = drir; - return NoFault; + *data64 = 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; + *data64 = ipint; + break; case TSDEV_CC_ITIR: - *(uint64_t*)data = itint; - return NoFault; + *data64 = 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); + DPRINTFN("Tsunami CChip: read regnum=%#x size=%d data=%lld\n", regnum, + req->size, *data); - return NoFault; + pkt.result = Success; + return pioDelay; } -Fault -TsunamiCChip::write(MemReqPtr &req, const uint8_t *data) +Tick +TsunamiCChip::write(Packet &pkt) { + pkt.time = curTick + pioDelay; + + + assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); + Addr daddr = pkt.addr - pioAddr; + + uint64_t val = *(uint64_t *)pkt.data; + assert(pkt.size == sizeof(uint64_t)); + DPRINTF(Tsunami, "write - va=%#x value=%#x size=%d \n", req->vaddr, *(uint64_t*)data, req->size); 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/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 7b72b7ef4..bbb42c065 100644 --- a/dev/uart8250.cc +++ b/dev/uart8250.cc @@ -40,10 +40,6 @@ #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; @@ -100,26 +96,35 @@ 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); + assert(pkt.result == Unknown); + assert(pkt.addr > pioAddr && pkt.addr < pioAddr + pioSize); + assert(pkt.size == 1); + + pkt.time = curTick + pioDelay; + Addr daddr = pkt.addr - pioAddr; + uint8_t *data; + DPRINTF(Uart, " read register %#x\n", daddr); - assert(req->size == 1); + if (!pkt.data) { + data = new uint8_t; + pkt.data = data; + } else + data = pkt.data; switch (daddr) { case 0x0: @@ -127,7 +132,7 @@ Uart8250::read(MemReqPtr &req, uint8_t *data) if (cons->dataAvailable()) cons->in(*data); else { - *(uint8_t*)data = 0; + *data = 0; // A limited amount of these are ok. DPRINTF(Uart, "empty read of RX register\n"); } @@ -142,7 +147,7 @@ Uart8250::read(MemReqPtr &req, uint8_t *data) break; case 0x1: if (!(LCR & 0x80)) { // Intr Enable Register(IER) - *(uint8_t*)data = IER; + *data = IER; } else { // DLM divisor latch MSB ; } @@ -151,17 +156,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; + *data = IIR_RXID; else if (status & TX_INT) - *(uint8_t*)data = IIR_TXID; + *data = IIR_TXID; else - *(uint8_t*)data = IIR_NOPEND; + *data = IIR_NOPEND; //Tx interrupts are cleared on IIR reads status &= ~TX_INT; break; case 0x3: // Line Control Register (LCR) - *(uint8_t*)data = LCR; + *data = LCR; break; case 0x4: // Modem Control Register (MCR) break; @@ -172,34 +177,41 @@ 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; + *data = lsr; break; case 0x6: // Modem Status Register (MSR) - *(uint8_t*)data = 0; + *data = 0; break; case 0x7: // Scratch Register (SCR) - *(uint8_t*)data = 0; // doesn't exist with at 8250. + *data = 0; // doesn't exist with at 8250. break; default: panic("Tried to access a UART port that doesn't exist\n"); break; } - return NoFault; - + 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 = curTick + pioDelay; + Addr daddr = pkt.addr - pioAddr; + + uint8_t *data = pkt.data; + + DPRINTF(Uart, " write register %#x value %#x\n", daddr, *data); switch (daddr) { case 0x0: if (!(LCR & 0x80)) { // write byte - cons->out(*(uint8_t *)data); + cons->out(*data); platform->clearConsoleInt(); status &= ~TX_INT; if (UART_IER_THRI & IER) @@ -210,7 +222,7 @@ Uart8250::write(MemReqPtr &req, const uint8_t *data) break; case 0x1: if (!(LCR & 0x80)) { // Intr Enable Register(IER) - IER = *(uint8_t*)data; + IER = *data; if (UART_IER_THRI & IER) { DPRINTF(Uart, "IER: IER_THRI set, scheduling TX intrrupt\n"); @@ -244,10 +256,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 = *data; break; case 0x4: // Modem Control Register (MCR) - if (*(uint8_t*)data == (UART_MCR_LOOP | 0x0A)) + if (*data == (UART_MCR_LOOP | 0x0A)) MCR = 0x9A; break; case 0x7: // Scratch Register (SCR) @@ -257,7 +269,7 @@ Uart8250::write(MemReqPtr &req, const uint8_t *data) panic("Tried to access a UART port that doesn't exist\n"); break; } - return NoFault; + return pioDelay; } void @@ -272,6 +284,14 @@ Uart8250::dataAvailable() } +void +Uart8250::addressRanges(AddrRangeList &range_list) +{ + assert(pioSize != 0); + range_list.clear(); + range_list.push_back(RangeSize(pioAddr, pioSize)); +} + void @@ -316,35 +336,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<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_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 = 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..76b17caf8 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" @@ -53,7 +53,6 @@ #define 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); /** |