diff options
Diffstat (limited to 'dev')
-rw-r--r-- | dev/alpha_console.cc | 119 | ||||
-rw-r--r-- | dev/alpha_console.hh | 15 | ||||
-rw-r--r-- | dev/io_device.cc | 18 | ||||
-rw-r--r-- | dev/io_device.hh | 30 | ||||
-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/uart.cc | 32 | ||||
-rw-r--r-- | dev/uart.hh | 26 | ||||
-rw-r--r-- | dev/uart8250.cc | 120 | ||||
-rw-r--r-- | dev/uart8250.hh | 14 |
11 files changed, 205 insertions, 198 deletions
diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc index ad3b16fc0..8c097fdd0 100644 --- a/dev/alpha_console.cc +++ b/dev/alpha_console.cc @@ -41,9 +41,10 @@ #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/physical.hh" #include "sim/builder.hh" #include "sim/sim_object.hh" @@ -51,13 +52,14 @@ using namespace std; using namespace AlphaISA; AlphaConsole::AlphaConsole(Params *p) - : PioDevice(p->name, p->platform), disk(p->disk), - console(params()->cons), system(params()->sys), cpu(params()->cpu), - pioSize(sizeof(struct alphaAccess)) + : BasicPioDevice(p), disk(p->disk), + console(params()->cons), system(params()->alpha_sys), cpu(params()->cpu) { - alphaAccess = new Access; - alphaAccess->last_offset = size - 1; + pioSize = sizeof(struct AlphaAccess); + + alphaAccess = new Access(); + alphaAccess->last_offset = pioSize - 1; alphaAccess->version = ALPHA_ACCESS_VERSION; alphaAccess->diskUnit = 1; @@ -70,7 +72,7 @@ AlphaConsole::AlphaConsole(Params *p) alphaAccess->inputChar = 0; bzero(alphaAccess->cpuStack, sizeof(alphaAccess->cpuStack)); - system->setAlphaAccess(addr); + system->setAlphaAccess(pioAddr); } void @@ -82,13 +84,21 @@ 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))); +} + + Tick AlphaConsole::read(Packet &pkt) { - pkt.time = curTick + pioDelay; /** 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 @@ -97,25 +107,36 @@ AlphaConsole::read(Packet &pkt) assert(pkt.result == Unknown); assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); - Addr daddr = req.addr - pioAddr; - switch (req.size) + pkt.time = curTick + pioDelay; + Addr daddr = pkt.addr - pioAddr; + + uint32_t *data32; + uint64_t *data64; + + switch (pkt.size) { case sizeof(uint32_t): - if (!pkt.data) pkt.pkt.data = new uint32_t; + 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*)pkt.data = alphaAccess->last_offset; + *data32 = alphaAccess->last_offset; break; case offsetof(AlphaAccess, version): - *(uint32_t*)pkt.data = alphaAccess->version; + *data32 = alphaAccess->version; break; case offsetof(AlphaAccess, numCPUs): - *(uint32_t*)pkt.data = alphaAccess->numCPUs; + *data32 = alphaAccess->numCPUs; break; case offsetof(AlphaAccess, intrClockFrequency): - *(uint32_t*)pkt.data = alphaAccess->intrClockFrequency; + *data32 = alphaAccess->intrClockFrequency; break; default: /* Old console code read in everyting as a 32bit int @@ -123,60 +144,63 @@ AlphaConsole::read(Packet &pkt) */ pkt.result = BadAddress; } - DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, - *(uint32_t*)pkt.data); + DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, *data32); break; case sizeof(uint64_t): - if (!pkt.data) pkt.pkt.data = new uint64_t; + 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*)pkt.data = console->console_in(); + *data64 = console->console_in(); break; case offsetof(AlphaAccess, cpuClock): - *(uint64_t*)pkt.data = alphaAccess->cpuClock; + *data64 = alphaAccess->cpuClock; break; case offsetof(AlphaAccess, mem_size): - *(uint64_t*)pkt.data = alphaAccess->mem_size; + *data64 = alphaAccess->mem_size; break; case offsetof(AlphaAccess, kernStart): - *(uint64_t*)pkt.data = alphaAccess->kernStart; + *data64 = alphaAccess->kernStart; break; case offsetof(AlphaAccess, kernEnd): - *(uint64_t*)pkt.data = alphaAccess->kernEnd; + *data64 = alphaAccess->kernEnd; break; case offsetof(AlphaAccess, entryPoint): - *(uint64_t*)pkt.data = alphaAccess->entryPoint; + *data64 = alphaAccess->entryPoint; break; case offsetof(AlphaAccess, diskUnit): - *(uint64_t*)pkt.data = alphaAccess->diskUnit; + *data64 = alphaAccess->diskUnit; break; case offsetof(AlphaAccess, diskCount): - *(uint64_t*)pkt.data = alphaAccess->diskCount; + *data64 = alphaAccess->diskCount; break; case offsetof(AlphaAccess, diskPAddr): - *(uint64_t*)pkt.data = alphaAccess->diskPAddr; + *data64 = alphaAccess->diskPAddr; break; case offsetof(AlphaAccess, diskBlock): - *(uint64_t*)pkt.data = alphaAccess->diskBlock; + *data64 = alphaAccess->diskBlock; break; case offsetof(AlphaAccess, diskOperation): - *(uint64_t*)pkt.data = alphaAccess->diskOperation; + *data64 = alphaAccess->diskOperation; break; case offsetof(AlphaAccess, outputChar): - *(uint64_t*)pkt.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*)pkt.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, - *(uint64_t*)data); + DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, *data64); break; default: pkt.result = BadAddress; @@ -186,15 +210,15 @@ AlphaConsole::read(Packet &pkt) } Tick -AlphaConsole::write(MemReqPtr &req, const uint8_t *data) +AlphaConsole::write(Packet &pkt) { pkt.time = curTick + pioDelay; assert(pkt.result == Unknown); assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); - Addr daddr = req.addr - pioAddr; + Addr daddr = pkt.addr - pioAddr; - uint64_t val = *(uint64_t *)data; + uint64_t val = *(uint64_t *)pkt.data; assert(pkt.size == sizeof(uint64_t)); switch (daddr) { @@ -303,14 +327,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) @@ -318,21 +339,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 6f3ea15a6..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 BasePioDevice +class AlphaConsole : public BasicPioDevice { protected: struct Access : public AlphaAccess @@ -97,12 +96,12 @@ class AlphaConsole : public BasePioDevice BaseCPU *cpu; public: - struct Params : public BasePioDevice::Params + struct Params : public BasicPioDevice::Params { SimConsole *cons; SimpleDisk *disk; - AlphaSystem *sys; - BaseCpu *cpu; + AlphaSystem *alpha_sys; + BaseCPU *cpu; }; protected: const Params *params() const {return (const Params *)_params; } @@ -120,14 +119,14 @@ class AlphaConsole : public BasePioDevice 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 ac993d78d..5d3a87006 100644 --- a/dev/io_device.cc +++ b/dev/io_device.cc @@ -48,9 +48,10 @@ PioPort::recvFunctional(Packet &pkt) } void -PioPort::getDeviceAddressRanges(AddrRangeList &range_list, bool &owner) +PioPort::getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) { - device->addressRanges(range_list, owner); + snoop.clear(); + device->addressRanges(resp); } @@ -100,8 +101,8 @@ DmaPort::recvTiming(Packet &pkt) return Success; } -DmaDevice::DmaDevice(const std::string &name, Platform *p) - : PioDevice(name, p) +DmaDevice::DmaDevice(Params *p) + : PioDevice(p) { dmaPort = new DmaPort(this); } @@ -195,13 +196,4 @@ DmaDevice::~DmaDevice() delete dmaPort; } -void -BasePioDevice::addressRanges(AddrRangeList &range_list, bool &owner) -{ - assert(pioSize != 0); - owner = true; - range_list.clear(); - range_list.push_back(RangeSize(pio_addr, sizeof(struct alphaAccess))); -} - diff --git a/dev/io_device.hh b/dev/io_device.hh index e2565cfdc..a81dae072 100644 --- a/dev/io_device.hh +++ b/dev/io_device.hh @@ -37,6 +37,7 @@ class Platform; class PioDevice; class DmaDevice; +class System; /** * The PioPort class is a programmed i/o port that all devices that are @@ -75,7 +76,7 @@ class PioPort : public Port virtual void recvStatusChange(Status status) { peerStatus = status; } - virtual void getDeviceAddressRanges(AddrRangeList &range_list, bool &owner); + virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop); /** * This class is used to implemented sendTiming() with a delay. When a delay @@ -131,8 +132,8 @@ class DmaPort : public Port virtual Packet *recvRetry() ; - virtual void getDeviceAddressRanges(AddrRangeList &range_list, bool &owner) - { range_list.clear(); owner = true; } + virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) + { resp.clear(); snoop.clear(); } class SendEvent : public Event { @@ -183,7 +184,7 @@ class PioDevice : public SimObject * that it sees. */ PioPort *pioPort; - virtual void addressRanges(AddrRangeList &range_list, bool &owner) = 0; + 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. */ @@ -207,27 +208,29 @@ class PioDevice : public SimObject { std::string name; Platform *platform; + System *system; }; + protected: Params *_params; public: const Params *params() const { return _params; } - PioDevice(Params *params) - : SimObject(params()->name), platform(params()->platform) + PioDevice(Params *p) + : SimObject(params()->name), platform(p->platform), _params(p) {} virtual ~PioDevice(); 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; @@ -237,7 +240,7 @@ class PioDevice : public SimObject class BasicPioDevice : public PioDevice { public: - struct Params + struct Params : public PioDevice::Params { Addr pio_addr; Tick pio_delay; @@ -248,17 +251,16 @@ class BasicPioDevice : public PioDevice Addr pioAddr; /** Size that the device's address range. */ - Addr pioSize = 0; + Addr pioSize; /** Delay that the device experinces on an access. */ Tick pioDelay; public: - BasePioDevice(Params *p) - : PioDevice(p), pioAddr(p->pio_addr), pioDelay(p->pioDelay) + BasicPioDevice(Params *p) + : PioDevice(p), pioAddr(p->pio_addr), pioSize(0), pioDelay(p->pio_delay) {} - virtual void addressRanges(AddrRangeList &range_list, bool &owner); }; class DmaDevice : public PioDevice @@ -267,7 +269,7 @@ class DmaDevice : public PioDevice DmaPort *dmaPort; public: - DmaDevice(const std::string &name, Platform *p); + DmaDevice(Params *p); virtual ~DmaDevice(); virtual Port *getPort(const std::string &if_name) 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/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); /** |