diff options
Diffstat (limited to 'dev')
-rw-r--r-- | dev/alpha_console.cc | 12 | ||||
-rw-r--r-- | dev/alpha_console.hh | 9 | ||||
-rw-r--r-- | dev/baddev.cc | 68 | ||||
-rw-r--r-- | dev/baddev.hh | 65 | ||||
-rw-r--r-- | dev/console.cc | 4 | ||||
-rw-r--r-- | dev/pciconfigall.cc | 190 | ||||
-rw-r--r-- | dev/pciconfigall.hh | 91 | ||||
-rw-r--r-- | dev/pcidev.cc | 369 | ||||
-rw-r--r-- | dev/pcidev.hh | 98 | ||||
-rw-r--r-- | dev/platform.hh | 59 | ||||
-rw-r--r-- | dev/tsunami.cc | 93 | ||||
-rw-r--r-- | dev/tsunami.hh | 108 | ||||
-rw-r--r-- | dev/tsunami_cchip.cc | 312 | ||||
-rw-r--r-- | dev/tsunami_cchip.hh | 90 | ||||
-rw-r--r-- | dev/tsunami_io.cc | 383 | ||||
-rw-r--r-- | dev/tsunami_io.hh | 138 | ||||
-rw-r--r-- | dev/tsunami_pchip.cc | 260 | ||||
-rw-r--r-- | dev/tsunami_pchip.hh | 74 | ||||
-rw-r--r-- | dev/tsunami_uart.cc | 219 | ||||
-rw-r--r-- | dev/tsunami_uart.hh | 64 | ||||
-rw-r--r-- | dev/tsunamireg.h | 110 |
21 files changed, 2806 insertions, 10 deletions
diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc index 2dc939b97..e1b69c3ce 100644 --- a/dev/alpha_console.cc +++ b/dev/alpha_console.cc @@ -46,13 +46,15 @@ #include "mem/functional_mem/memory_control.hh" #include "sim/builder.hh" #include "sim/system.hh" +#include "dev/tsunami_io.hh" using namespace std; -AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d, - System *system, BaseCPU *cpu, TlaserClock *clock, - int num_cpus, MemoryController *mmu, Addr a) - : FunctionalMemory(name), disk(d), console(cons), addr(a) +AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, + SimpleDisk *d, int size, System *system, + BaseCPU *cpu, TsunamiIO *clock, int num_cpus, + Addr addr, Addr mask, MemoryController *mmu) + : MmapDevice(name, addr, mask, mmu), disk(d), console(cons) { mmu->add_child(this, Range<Addr>(addr, addr + size)); @@ -250,7 +252,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) Param<Addr> addr; SimObjectParam<System *> system; SimObjectParam<BaseCPU *> cpu; - SimObjectParam<TlaserClock *> clock; + SimObjectParam<TsunamiIO *> clock; END_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) diff --git a/dev/alpha_console.hh b/dev/alpha_console.hh index 54a2af6d5..29ebec1bb 100644 --- a/dev/alpha_console.hh +++ b/dev/alpha_console.hh @@ -37,6 +37,7 @@ #include "dev/alpha_access.h" #include "mem/functional_mem/functional_memory.hh" #include "sim/host.hh" +#include "dev/tsunami_io.hh" class BaseCPU; class SimConsole; @@ -88,9 +89,11 @@ class AlphaConsole : public FunctionalMemory public: /** Standard Constructor */ - AlphaConsole(const std::string &name, SimConsole *cons, SimpleDisk *d, - System *system, BaseCPU *cpu, TlaserClock *clock, - int num_cpus, MemoryController *mmu, Addr addr); + AlphaConsole(const std::string &name, SimConsole *cons, + SimpleDisk *d, int size, + System *system, BaseCPU *cpu, + TsunamiIO *clock, int num_cpus, + Addr addr, Addr mask, MemoryController *mmu); /** * memory mapped reads and writes diff --git a/dev/baddev.cc b/dev/baddev.cc new file mode 100644 index 000000000..d91069bae --- /dev/null +++ b/dev/baddev.cc @@ -0,0 +1,68 @@ +/* $Id$ */ + +/* @file + * BadDevice implemenation + */ + +#include <deque> +#include <string> +#include <vector> + +#include "base/trace.hh" +#include "cpu/exec_context.hh" +#include "dev/scsi_ctrl.hh" +#include "dev/baddev.hh" +#include "dev/tsunamireg.h" +#include "dev/tsunami.hh" +#include "mem/functional_mem/memory_control.hh" +#include "sim/builder.hh" +#include "sim/system.hh" + +using namespace std; + +BadDevice::BadDevice(const string &name, + Addr addr, Addr mask, MemoryController *mmu, const string &devicename) + : MmapDevice(name, addr, mask, mmu), devname(devicename) +{ +} + +Fault +BadDevice::read(MemReqPtr &req, uint8_t *data) +{ + + panic("Device %s not imlpmented\n", devname); + return No_Fault; +} + +Fault +BadDevice::write(MemReqPtr &req, const uint8_t *data) +{ + panic("Device %s not imlpmented\n", devname); + return No_Fault; +} + + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(BadDevice) + + SimObjectParam<MemoryController *> mmu; + Param<Addr> addr; + Param<Addr> mask; + Param<string> devicename; + +END_DECLARE_SIM_OBJECT_PARAMS(BadDevice) + +BEGIN_INIT_SIM_OBJECT_PARAMS(BadDevice) + + INIT_PARAM(mmu, "Memory Controller"), + INIT_PARAM(addr, "Device Address"), + INIT_PARAM(mask, "Address Mask"), + INIT_PARAM(devicename, "Name of device to error on") + +END_INIT_SIM_OBJECT_PARAMS(BadDevice) + +CREATE_SIM_OBJECT(BadDevice) +{ + return new BadDevice(getInstanceName(), addr, mask, mmu, devicename); +} + +REGISTER_SIM_OBJECT("BadDevice", BadDevice) diff --git a/dev/baddev.hh b/dev/baddev.hh new file mode 100644 index 000000000..29fc5f44d --- /dev/null +++ b/dev/baddev.hh @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2003 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* @file + * This devices just panics when touched. For example if you have a + * kernel that touches the frame buffer which isn't allowed. + */ + +#ifndef __BADDEV_HH__ +#define __BADDEV_HH__ + +#include "mem/functional_mem/mmap_device.hh" + +/** + * BadDevice + * This device just panics when accessed. It is supposed to warn + * the user that the kernel they are running has unsupported + * options (i.e. frame buffer) + */ +class BadDevice : public MmapDevice +{ + private: + + std::string devname; + protected: + + public: + /** + * The default constructor. + */ + BadDevice(const std::string &name, Addr addr, Addr mask, + MemoryController *mmu, const std::string &devicename); + + virtual Fault read(MemReqPtr &req, uint8_t *data); + virtual Fault write(MemReqPtr &req, const uint8_t *data); + + +}; + +#endif // __BADDEV_HH__ diff --git a/dev/console.cc b/dev/console.cc index 5e7b0abf6..fb74c388a 100644 --- a/dev/console.cc +++ b/dev/console.cc @@ -413,8 +413,8 @@ CREATE_SIM_OBJECT(SimConsole) SimConsole *console = new SimConsole(getInstanceName(), filename, number); ((ConsoleListener *)listener)->add(console); ((SimConsole *)console)->initInt(intr_control); - ((SimConsole *)console)->setInt(SimConsole::TransmitInterrupt | - SimConsole::ReceiveInterrupt); +// ((SimConsole *)console)->setInt(SimConsole::TransmitInterrupt | +// SimConsole::ReceiveInterrupt); return console; } diff --git a/dev/pciconfigall.cc b/dev/pciconfigall.cc new file mode 100644 index 000000000..1b19ec368 --- /dev/null +++ b/dev/pciconfigall.cc @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2003 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* @file + * PCI Configspace implementation + */ + +#include <deque> +#include <string> +#include <vector> + +#include "base/trace.hh" +#include "cpu/exec_context.hh" +#include "dev/scsi_ctrl.hh" +#include "dev/pciconfigall.hh" +#include "dev/pcidev.hh" +#include "dev/tsunamireg.h" +#include "dev/tsunami.hh" +#include "mem/functional_mem/memory_control.hh" +#include "sim/builder.hh" +#include "sim/system.hh" + +using namespace std; + +PCIConfigAll::PCIConfigAll(const string &name, Tsunami *t, + Addr addr, Addr mask, MemoryController *mmu) + : MmapDevice(name, addr, mask, mmu), tsunami(t) +{ + // Put back pointer in tsunami + tsunami->pciconfig = this; + + // Make all the pointers to devices null + for(int x=0; x < MAX_PCI_DEV; x++) + for(int y=0; y < MAX_PCI_FUNC; y++) + devices[x][y] = NULL; +} + +Fault +PCIConfigAll::read(MemReqPtr &req, uint8_t *data) +{ + DPRINTF(PCIConfigAll, "read va=%#x size=%d\n", + req->vaddr, req->size); + + Addr daddr = (req->paddr & addr_mask); + + 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 No_Fault; + case sizeof(uint32_t): + *(uint32_t*)data = 0xFFFFFFFF; + return No_Fault; + case sizeof(uint16_t): + *(uint16_t*)data = 0xFFFF; + return No_Fault; + case sizeof(uint8_t): + *(uint8_t*)data = 0xFF; + return No_Fault; + 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 No_Fault; + default: + panic("invalid access size(?) for PCI configspace!\n"); + } + } + + DPRINTFN("Tsunami PCI Configspace ERROR: read daddr=%#x size=%d\n", + daddr, req->size); + + return No_Fault; +} + +Fault +PCIConfigAll::write(MemReqPtr &req, const uint8_t *data) +{ + Addr daddr = (req->paddr & addr_mask); + + int device = (daddr >> 11) & 0x1F; + int func = (daddr >> 8) & 0x7; + int reg = daddr & 0xFF; + + union { + uint8_t byte_value; + uint16_t half_value; + uint32_t word_value; + }; + + if (devices[device][func] == NULL) + panic("Attempting to write to config space on non-existant device\n"); + else { + switch (req->size) { + case sizeof(uint8_t): + byte_value = *(uint8_t*)data; + break; + case sizeof(uint16_t): + half_value = *(uint16_t*)data; + break; + case sizeof(uint32_t): + word_value = *(uint32_t*)data; + break; + default: + panic("invalid access size(?) for PCI configspace!\n"); + } + } + + DPRINTF(PCIConfigAll, "write - va=%#x size=%d data=%#x\n", + req->vaddr, req->size, word_value); + + devices[device][func]->WriteConfig(reg, req->size, word_value); + + return No_Fault; +} + +void +PCIConfigAll::serialize(std::ostream &os) +{ + // code should be written +} + +void +PCIConfigAll::unserialize(Checkpoint *cp, const std::string §ion) +{ + //code should be written +} + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(PCIConfigAll) + + SimObjectParam<Tsunami *> tsunami; + SimObjectParam<MemoryController *> mmu; + Param<Addr> addr; + Param<Addr> mask; + +END_DECLARE_SIM_OBJECT_PARAMS(PCIConfigAll) + +BEGIN_INIT_SIM_OBJECT_PARAMS(PCIConfigAll) + + INIT_PARAM(tsunami, "Tsunami"), + INIT_PARAM(mmu, "Memory Controller"), + INIT_PARAM(addr, "Device Address"), + INIT_PARAM(mask, "Address Mask") + +END_INIT_SIM_OBJECT_PARAMS(PCIConfigAll) + +CREATE_SIM_OBJECT(PCIConfigAll) +{ + return new PCIConfigAll(getInstanceName(), tsunami, addr, mask, mmu); +} + +REGISTER_SIM_OBJECT("PCIConfigAll", PCIConfigAll) + +#endif // DOXYGEN_SHOULD_SKIP_THIS diff --git a/dev/pciconfigall.hh b/dev/pciconfigall.hh new file mode 100644 index 000000000..070643fd9 --- /dev/null +++ b/dev/pciconfigall.hh @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2003 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * @todo + * Should derive Tsunami from common platform class so PCI will work with + * multiple platforms + * + * @file + * PCI Config space implementation. + */ + +#ifndef __PCICONFIGALL_HH__ +#define __PCICONFIGALL_HH__ + +#include "mem/functional_mem/mmap_device.hh" +#include "dev/tsunami.hh" +#include "dev/pcireg.h" + +#define MAX_PCI_DEV 32 +#define MAX_PCI_FUNC 8 + +class PciDev; + +/** + * PCI Config Space + * All of PCI config space needs to return -1 on Tsunami, except + * the devices that exist. This device maps the entire bus config + * space and passes the requests on to TsunamiPCIDev devices as + * appropriate. + */ +class PCIConfigAll : public MmapDevice +{ + private: + + protected: + + /** + * Pointer to the Tsunmi Object so we can communicate + * to other Tsunami devices in need be. + * @todo Make this more generic for multiple platforms + */ + Tsunami *tsunami; + + public: + /** + * Pointers to all the devices that are registered with this + * particular config space. + */ + PciDev* devices[MAX_PCI_DEV][MAX_PCI_FUNC]; + + /** + * The default constructor. + */ + PCIConfigAll(const std::string &name, Tsunami *t, + Addr addr, Addr mask, MemoryController *mmu); + + virtual Fault read(MemReqPtr &req, uint8_t *data); + virtual Fault write(MemReqPtr &req, const uint8_t *data); + + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); + +}; + +#endif // __PCICONFIGALL_HH__ diff --git a/dev/pcidev.cc b/dev/pcidev.cc new file mode 100644 index 000000000..9d9fbcd89 --- /dev/null +++ b/dev/pcidev.cc @@ -0,0 +1,369 @@ +/* + * Copyright (c) 2003 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* @file + * A single PCI device configuration space entry. + */ + +#include <list> +#include <sstream> +#include <string> +#include <vector> + +#include "base/inifile.hh" +#include "base/misc.hh" +#include "base/str.hh" // for to_number +#include "base/trace.hh" +#include "dev/pciareg.h" +#include "dev/scsi_ctrl.hh" +#include "dev/pcidev.hh" +#include "dev/pciconfigall.hh" +#include "mem/functional_mem/memory_control.hh" +#include "sim/builder.hh" +#include "sim/param.hh" +#include "sim/universe.hh" +#include "dev/tsunamireg.h" + +using namespace std; + +PciDev::PciDev(const string &name, MemoryController *mmu, PCIConfigAll *cf, + PciConfigData *cd, uint32_t bus, uint32_t dev, uint32_t func) + : MmapDevice(name), MMU(mmu), ConfigSpace(cf), ConfigData(cd), + Bus(bus), Device(dev), Function(func) +{ + // copy the config data from the PciConfigData object + if (cd) { + memcpy(config.data, cd->config.data, sizeof(config.data)); + memcpy(BARSize, cd->BARSize, sizeof(BARSize)); + memcpy(BARAddrs, cd->BARAddrs, sizeof(BARAddrs)); + } else + panic("NULL pointer to configuration data"); + + // Setup pointer in config space to point to this entry + if (cf->devices[dev][func] != NULL) + panic("Two PCI devices occuping same dev: %#x func: %#x", dev, func); + else + cf->devices[dev][func] = this; +} + +void +PciDev::ReadConfig(int offset, int size, uint8_t *data) +{ + switch(size) { + case sizeof(uint32_t): + memcpy((uint32_t*)data, config.data + offset, sizeof(uint32_t)); + DPRINTF(PCIDEV, + "read device: %#x function: %#x register: %#x data: %#x\n", + Device, Function, offset, *(uint32_t*)(config.data + offset)); + break; + + case sizeof(uint16_t): + memcpy((uint16_t*)data, config.data + offset, sizeof(uint16_t)); + DPRINTF(PCIDEV, + "read device: %#x function: %#x register: %#x data: %#x\n", + Device, Function, offset, *(uint16_t*)(config.data + offset)); + break; + + case sizeof(uint8_t): + memcpy((uint8_t*)data, config.data + offset, sizeof(uint8_t)); + printf("data: %#x\n", *(uint8_t*)(config.data + offset)); + DPRINTF(PCIDEV, + "read device: %#x function: %#x register: %#x data: %#x\n", + Device, Function, offset, *(uint8_t*)(config.data + offset)); + break; + + default: + panic("Invalid Read Size"); + } +} + +void +PciDev::WriteConfig(int offset, int size, uint32_t data) +{ + uint32_t barnum; + + union { + uint8_t byte_value; + uint16_t half_value; + uint32_t word_value; + }; + word_value = data; + + DPRINTF(PCIDEV, + "write device: %#x function: %#x reg: %#x size: %#x data: %#x\n", + Device, Function, offset, size, word_value); + + barnum = (offset - PCI0_BASE_ADDR0) >> 2; + + switch (size) { + case sizeof(uint8_t): // 1-byte access + switch (offset) { + case PCI0_INTERRUPT_LINE: + case PCI_CACHE_LINE_SIZE: + case PCI_LATENCY_TIMER: + *(uint8_t *)&config.data[offset] = byte_value; + break; + + default: + panic("writing to a read only register"); + } + break; + + case sizeof(uint16_t): // 2-byte access + switch (offset) { + case PCI_COMMAND: + case PCI_STATUS: + case PCI_CACHE_LINE_SIZE: + *(uint16_t *)&config.data[offset] = half_value; + break; + + default: + panic("writing to a read only register"); + } + break; + + case sizeof(uint16_t)+1: // 3-byte access + panic("invalid access size"); + + 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: + // Writing 0xffffffff to a BAR tells the card to set the + // value of the bar + // to size of memory it needs + if (word_value == 0xffffffff) { + // This is I/O Space, bottom two bits are read only + if (config.data[offset] & 0x1) { + *(uint32_t *)&config.data[offset] = + ~(BARSize[barnum] - 1) | + (config.data[offset] & 0x3); + } else { + // This is memory space, bottom four bits are read only + *(uint32_t *)&config.data[offset] = + ~(BARSize[barnum] - 1) | + (config.data[offset] & 0xF); + } + } else { + // This is I/O Space, bottom two bits are read only + if(config.data[offset] & 0x1) { + *(uint32_t *)&config.data[offset] = (word_value & ~0x3) | + (config.data[offset] & 0x3); + + if (word_value & ~0x1) { + // It's never been set + if (BARAddrs[barnum] == 0) + AddMapping((word_value & ~0x1) + TSUNAMI_PCI0_IO, + BARSize[barnum]-1, MMU); + else + ChangeMapping(BARAddrs[barnum], BARSize[barnum]-1, + (word_value & ~0x1) + TSUNAMI_PCI0_IO, + BARSize[barnum]-1, MMU); + BARAddrs[barnum] = (word_value & ~0x1) + TSUNAMI_PCI0_IO; + } + + } else { + // This is memory space, bottom four bits are read only + *(uint32_t *)&config.data[offset] = (word_value & ~0xF) | + (config.data[offset] & 0xF); + + if (word_value & ~0x3) { + // It's never been set + if (BARAddrs[barnum] == 0) + AddMapping((word_value & ~0x3) + TSUNAMI_PCI0_MEMORY, + BARSize[barnum]-1, MMU); + else + ChangeMapping(BARAddrs[barnum], BARSize[barnum]-1, + (word_value & ~0x3) + + TSUNAMI_PCI0_MEMORY, + BARSize[barnum]-1, MMU); + BARAddrs[barnum] = (word_value & ~0x3) + + TSUNAMI_PCI0_MEMORY; + } + } + } + break; + + case PCI0_ROM_BASE_ADDR: + if (word_value == 0xfffffffe) + *(uint32_t *)&config.data[offset] = 0xffffffff; + else + *(uint32_t *)&config.data[offset] = word_value; + 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 + *(uint16_t *)&config.data[offset] = half_value; + break; + + default: + panic("writing to a read only register"); + } + break; + } +} + +void +PciDev::serialize(ostream &os) +{ + SERIALIZE_ARRAY(config.data, 64); +} + +void +PciDev::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_ARRAY(config.data, 64); +} + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(PciConfigData) + + Param<int> VendorID; + Param<int> DeviceID; + Param<int> Command; + Param<int> Status; + Param<int> Revision; + Param<int> ProgIF; + Param<int> SubClassCode; + Param<int> ClassCode; + Param<int> CacheLineSize; + Param<int> LatencyTimer; + Param<int> HeaderType; + Param<int> BIST; + Param<uint32_t> BAR0; + Param<uint32_t> BAR1; + Param<uint32_t> BAR2; + Param<uint32_t> BAR3; + Param<uint32_t> BAR4; + Param<uint32_t> BAR5; + Param<uint32_t> CardbusCIS; + Param<int> SubsystemVendorID; + Param<int> SubsystemID; + Param<uint32_t> ExpansionROM; + Param<int> InterruptLine; + Param<int> InterruptPin; + Param<int> MinimumGrant; + Param<int> MaximumLatency; + Param<uint32_t> BAR0Size; + Param<uint32_t> BAR1Size; + Param<uint32_t> BAR2Size; + Param<uint32_t> BAR3Size; + Param<uint32_t> BAR4Size; + Param<uint32_t> BAR5Size; + +END_DECLARE_SIM_OBJECT_PARAMS(PciConfigData) + +BEGIN_INIT_SIM_OBJECT_PARAMS(PciConfigData) + + INIT_PARAM(VendorID, "Vendor ID"), + INIT_PARAM(DeviceID, "Device ID"), + INIT_PARAM_DFLT(Command, "Command Register", 0x00), + INIT_PARAM_DFLT(Status, "Status Register", 0x00), + INIT_PARAM_DFLT(Revision, "Device Revision", 0x00), + INIT_PARAM_DFLT(ProgIF, "Programming Interface", 0x00), + INIT_PARAM(SubClassCode, "Sub-Class Code"), + INIT_PARAM(ClassCode, "Class Code"), + INIT_PARAM_DFLT(CacheLineSize, "System Cacheline Size", 0x00), + INIT_PARAM_DFLT(LatencyTimer, "PCI Latency Timer", 0x00), + INIT_PARAM_DFLT(HeaderType, "PCI Header Type", 0x00), + INIT_PARAM_DFLT(BIST, "Built In Self Test", 0x00), + INIT_PARAM_DFLT(BAR0, "Base Address Register 0", 0x00), + INIT_PARAM_DFLT(BAR1, "Base Address Register 1", 0x00), + INIT_PARAM_DFLT(BAR2, "Base Address Register 2", 0x00), + INIT_PARAM_DFLT(BAR3, "Base Address Register 3", 0x00), + INIT_PARAM_DFLT(BAR4, "Base Address Register 4", 0x00), + INIT_PARAM_DFLT(BAR5, "Base Address Register 5", 0x00), + INIT_PARAM_DFLT(CardbusCIS, "Cardbus Card Information Structure", 0x00), + INIT_PARAM_DFLT(SubsystemVendorID, "Subsystem Vendor ID", 0x00), + INIT_PARAM_DFLT(SubsystemID, "Subsystem ID", 0x00), + INIT_PARAM_DFLT(ExpansionROM, "Expansion ROM Base Address Register", 0x00), + INIT_PARAM(InterruptLine, "Interrupt Line Register"), + INIT_PARAM(InterruptPin, "Interrupt Pin Register"), + INIT_PARAM_DFLT(MinimumGrant, "Minimum Grant", 0x00), + INIT_PARAM_DFLT(MaximumLatency, "Maximum Latency", 0x00), + INIT_PARAM_DFLT(BAR0Size, "Base Address Register 0 Size", 0x00), + INIT_PARAM_DFLT(BAR1Size, "Base Address Register 1 Size", 0x00), + INIT_PARAM_DFLT(BAR2Size, "Base Address Register 2 Size", 0x00), + INIT_PARAM_DFLT(BAR3Size, "Base Address Register 3 Size", 0x00), + INIT_PARAM_DFLT(BAR4Size, "Base Address Register 4 Size", 0x00), + INIT_PARAM_DFLT(BAR5Size, "Base Address Register 5 Size", 0x00) + +END_INIT_SIM_OBJECT_PARAMS(PciConfigData) + +CREATE_SIM_OBJECT(PciConfigData) +{ + PciConfigData *data = new PciConfigData(getInstanceName()); + + data->config.hdr.vendor = VendorID; + data->config.hdr.device = DeviceID; + data->config.hdr.command = Command; + data->config.hdr.status = Status; + data->config.hdr.revision = Revision; + data->config.hdr.progIF = ProgIF; + data->config.hdr.subClassCode = SubClassCode; + data->config.hdr.classCode = ClassCode; + data->config.hdr.cacheLineSize = CacheLineSize; + data->config.hdr.latencyTimer = LatencyTimer; + data->config.hdr.headerType = HeaderType; + data->config.hdr.bist = BIST; + + data->config.hdr.pci0.baseAddr0 = BAR0; + data->config.hdr.pci0.baseAddr1 = BAR1; + data->config.hdr.pci0.baseAddr2 = BAR2; + data->config.hdr.pci0.baseAddr3 = BAR3; + data->config.hdr.pci0.baseAddr4 = BAR4; + data->config.hdr.pci0.baseAddr5 = BAR5; + data->config.hdr.pci0.cardbusCIS = CardbusCIS; + data->config.hdr.pci0.subsystemVendorID = SubsystemVendorID; + data->config.hdr.pci0.subsystemID = SubsystemVendorID; + data->config.hdr.pci0.expansionROM = ExpansionROM; + data->config.hdr.pci0.interruptLine = InterruptLine; + data->config.hdr.pci0.interruptPin = InterruptPin; + data->config.hdr.pci0.minimumGrant = MinimumGrant; + data->config.hdr.pci0.maximumLatency = MaximumLatency; + + data->BARSize[0] = BAR0Size; + data->BARSize[1] = BAR1Size; + data->BARSize[2] = BAR2Size; + data->BARSize[3] = BAR3Size; + data->BARSize[4] = BAR4Size; + data->BARSize[5] = BAR5Size; + + return data; +} + +REGISTER_SIM_OBJECT("PciConfigData", PciConfigData) + +#endif // DOXYGEN_SHOULD_SKIP_THIS diff --git a/dev/pcidev.hh b/dev/pcidev.hh new file mode 100644 index 000000000..8cb68945a --- /dev/null +++ b/dev/pcidev.hh @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2003 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* @file + * PCI configspace devices + */ + +#ifndef __PCI_DEV_HH__ +#define __PCI_DEV_HH__ + +#include "dev/pcireg.h" +#include "sim/sim_object.hh" +#include "mem/functional_mem/mmap_device.hh" + +class PCIConfigAll; +class MemoryController; + +class PciConfigData : public SimObject +{ + public: + PciConfigData(const std::string &name) + : SimObject(name) + { + memset(config.data, 0, sizeof(config.data)); + memset(BARAddrs, 0, sizeof(BARAddrs)); + memset(BARSize, 0, sizeof(BARSize)); + } + + PCIConfig config; + uint32_t BARSize[6]; + Addr BARAddrs[6]; +}; + +/** + * PCI device, base implemnation is only config space. + * Each device is connected to a PCIConfigSpace device + * which returns -1 for everything but the pcidevs that + * register with it. This object registers with the PCIConfig space + * object. + */ +class PciDev : public MmapDevice +{ + protected: + MemoryController *MMU; + PCIConfigAll *ConfigSpace; + PciConfigData *ConfigData; + uint32_t Bus; + uint32_t Device; + uint32_t Function; + + PCIConfig config; + uint32_t BARSize[6]; + Addr BARAddrs[6]; + + public: + PciDev(const std::string &name, MemoryController *mmu, PCIConfigAll *cf, + PciConfigData *cd, uint32_t bus, uint32_t dev, uint32_t func); + + virtual Fault read(MemReqPtr &req, uint8_t *data) { + return No_Fault; + } + virtual Fault write(MemReqPtr &req, const uint8_t *data) { + return No_Fault; + } + + virtual void WriteConfig(int offset, int size, uint32_t data); + virtual void ReadConfig(int offset, int size, uint8_t *data); + + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); +}; + +#endif // __PCI_DEV_HH__ diff --git a/dev/platform.hh b/dev/platform.hh new file mode 100644 index 000000000..4425570f2 --- /dev/null +++ b/dev/platform.hh @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2003 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Generic interface for platforms + */ + +#ifndef __PLATFORM_HH_ +#define __PLATFORM_HH_ + +#include "sim/sim_object.hh" + +class IntrControl; +class SimConsole; + +class Platform : public SimObject +{ + public: + /** Pointer to the interrupt controller */ + IntrControl *intrctrl; + /** Pointer to the simulation console */ + SimConsole *cons; + + int interrupt_frequency; + + public: + Platform(const std::string &name, SimConsole *con, IntrControl *intctrl, + int intrFreq) + : SimObject(name), intrctrl(intctrl), cons(con), + interrupt_frequency(intrFreq) {} +}; + +#endif // __PLATFORM_HH_ diff --git a/dev/tsunami.cc b/dev/tsunami.cc new file mode 100644 index 000000000..04ab922b9 --- /dev/null +++ b/dev/tsunami.cc @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2003 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <deque> +#include <string> +#include <vector> + +#include "cpu/intr_control.hh" +#include "dev/console.hh" +#include "dev/etherdev.hh" +#include "dev/adaptec_ctrl.hh" +#include "dev/tlaser_clock.hh" +#include "dev/tsunami_cchip.hh" +#include "dev/tsunami_pchip.hh" +#include "dev/tsunami.hh" +#include "sim/builder.hh" +#include "sim/system.hh" + +using namespace std; + +Tsunami::Tsunami(const string &name, System *s, SimConsole *con, + IntrControl *ic, int intr_freq) + : Platform(name, con, ic, intr_freq), system(s) +{ + // set the back pointer from the system to myself + system->platform = this; + + for (int i = 0; i < Tsunami::Max_CPUs; i++) + intr_sum_type[i] = 0; +} + +void +Tsunami::serialize(std::ostream &os) +{ + SERIALIZE_ARRAY(intr_sum_type, Tsunami::Max_CPUs); +} + +void +Tsunami::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_ARRAY(intr_sum_type, Tsunami::Max_CPUs); +} + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tsunami) + + SimObjectParam<System *> system; + SimObjectParam<SimConsole *> cons; + SimObjectParam<IntrControl *> intrctrl; + Param<int> interrupt_frequency; + +END_DECLARE_SIM_OBJECT_PARAMS(Tsunami) + +BEGIN_INIT_SIM_OBJECT_PARAMS(Tsunami) + + INIT_PARAM(system, "system"), + INIT_PARAM(cons, "system console"), + INIT_PARAM(intrctrl, "interrupt controller"), + INIT_PARAM_DFLT(interrupt_frequency, "frequency of interrupts", 1024) + +END_INIT_SIM_OBJECT_PARAMS(Tsunami) + +CREATE_SIM_OBJECT(Tsunami) +{ + return new Tsunami(getInstanceName(), system, cons, intrctrl, + interrupt_frequency); +} + +REGISTER_SIM_OBJECT("Tsunami", Tsunami) diff --git a/dev/tsunami.hh b/dev/tsunami.hh new file mode 100644 index 000000000..ef27ff18e --- /dev/null +++ b/dev/tsunami.hh @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2003 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Declaration of top level class for the Tsunami chipset. This class just + * retains pointers to all its children so the children can communicate. + */ + +#ifndef __TSUNAMI_HH__ +#define __TSUNAMI_HH__ + +#include "dev/platform.hh" + +class AdaptecController; +class TlaserClock; +class EtherDev; +class TsunamiCChip; +class TsunamiPChip; +class TsunamiIO; +class PCIConfigAll; +class System; + +/** + * Top level class for Tsunami Chipset emulation. + * This structure just contains pointers to all the + * children so the children can commnicate to do the + * read work + */ + +class Tsunami : public Platform +{ + public: + + /** Max number of CPUs in a Tsunami */ + static const int Max_CPUs = 4; + + /** Pointer to the system */ + System *system; + /** Pointer to the TsunamiIO device which has the RTC */ + TsunamiIO *io; + /** Pointer to the SCSI controller device */ + AdaptecController *scsi; + /** Pointer to the ethernet controller device */ + EtherDev *ethernet; + + /** Pointer to the Tsunami CChip. + * The chip contains some configuration information and + * all the interrupt mask and status registers + */ + TsunamiCChip *cchip; + + /** Pointer to the Tsunami PChip. + * The pchip is the interface to the PCI bus, in our case + * it does not have to do much. + */ + TsunamiPChip *pchip; + + /** Pointer to the PCI Config Space + * The config space in Tsunami all needs to return + * -1 if a device is not there. + */ + PCIConfigAll *pciconfig; + + int intr_sum_type[Tsunami::Max_CPUs]; + int ipi_pending[Tsunami::Max_CPUs]; + + public: + /** + * Constructor for the Tsunami Class. + * @param name name of the object + * @param con pointer to the console + * @param intrcontrol pointer to the interrupt controller + * @param intrFreq frequency that interrupts happen + */ + Tsunami(const std::string &name, System *s, SimConsole *con, + IntrControl *intctrl, int intrFreq); + + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); +}; + +#endif // __TSUNAMI_HH__ diff --git a/dev/tsunami_cchip.cc b/dev/tsunami_cchip.cc new file mode 100644 index 000000000..ceac5300f --- /dev/null +++ b/dev/tsunami_cchip.cc @@ -0,0 +1,312 @@ +/* $Id$ */ + +/* @file + * Emulation of the Tsunami CChip CSRs + */ + +#include <deque> +#include <string> +#include <vector> + +#include "base/trace.hh" +#include "cpu/exec_context.hh" +#include "dev/console.hh" +#include "dev/tsunami_cchip.hh" +#include "dev/tsunamireg.h" +#include "dev/tsunami.hh" +#include "cpu/intr_control.hh" +#include "mem/functional_mem/memory_control.hh" +#include "sim/builder.hh" +#include "sim/system.hh" + +using namespace std; + +TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, + Addr addr, Addr mask, MemoryController *mmu) + : MmapDevice(name, addr, mask, mmu), tsunami(t) +{ + for(int i=0; i < Tsunami::Max_CPUs; i++) { + dim[i] = 0; + dir[i] = 0; + dirInterrupting[i] = false; + } + + drir = 0; + misc = 0; + RTCInterrupting = false; + + //Put back pointer in tsunami + tsunami->cchip = this; +} + +Fault +TsunamiCChip::read(MemReqPtr &req, uint8_t *data) +{ + DPRINTF(Tsunami, "read va=%#x size=%d\n", + req->vaddr, req->size); + + Addr daddr = (req->paddr & addr_mask) >> 6; + ExecContext *xc = req->xc; + + switch (req->size) { + + case sizeof(uint64_t): + switch(daddr) { + case TSDEV_CC_CSR: + *(uint64_t*)data = 0x0; + return No_Fault; + case TSDEV_CC_MTR: + panic("TSDEV_CC_MTR not implemeted\n"); + return No_Fault; + case TSDEV_CC_MISC: + *(uint64_t*)data = misc | (xc->cpu_id & 0x3); + return No_Fault; + case TSDEV_CC_AAR0: + case TSDEV_CC_AAR1: + case TSDEV_CC_AAR2: + case TSDEV_CC_AAR3: + panic("TSDEV_CC_AARx not implemeted\n"); + return No_Fault; + case TSDEV_CC_DIM0: + *(uint64_t*)data = dim[0]; + return No_Fault; + case TSDEV_CC_DIM1: + *(uint64_t*)data = dim[1]; + return No_Fault; + case TSDEV_CC_DIM2: + *(uint64_t*)data = dim[2]; + return No_Fault; + case TSDEV_CC_DIM3: + *(uint64_t*)data = dim[3]; + return No_Fault; + case TSDEV_CC_DIR0: + *(uint64_t*)data = dir[0]; + return No_Fault; + case TSDEV_CC_DIR1: + *(uint64_t*)data = dir[1]; + return No_Fault; + case TSDEV_CC_DIR2: + *(uint64_t*)data = dir[2]; + return No_Fault; + case TSDEV_CC_DIR3: + *(uint64_t*)data = dir[3]; + return No_Fault; + case TSDEV_CC_DRIR: + *(uint64_t*)data = drir; + return No_Fault; + case TSDEV_CC_PRBEN: + panic("TSDEV_CC_PRBEN not implemented\n"); + return No_Fault; + case TSDEV_CC_IIC0: + case TSDEV_CC_IIC1: + case TSDEV_CC_IIC2: + case TSDEV_CC_IIC3: + panic("TSDEV_CC_IICx not implemented\n"); + return No_Fault; + case TSDEV_CC_MPR0: + case TSDEV_CC_MPR1: + case TSDEV_CC_MPR2: + case TSDEV_CC_MPR3: + panic("TSDEV_CC_MPRx not implemented\n"); + return No_Fault; + default: + panic("default in cchip read reached, accessing 0x%x\n"); + } // uint64_t + + break; + case sizeof(uint32_t): + case sizeof(uint16_t): + case sizeof(uint8_t): + default: + panic("invalid access size(?) for tsunami register!\n"); + } + DPRINTFN("Tsunami CChip ERROR: read daddr=%#x size=%d\n", daddr, req->size); + + return No_Fault; +} + +Fault +TsunamiCChip::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; + + switch (req->size) { + + case sizeof(uint64_t): + switch(daddr) { + case TSDEV_CC_CSR: + panic("TSDEV_CC_CSR write\n"); + return No_Fault; + case TSDEV_CC_MTR: + panic("TSDEV_CC_MTR write not implemented\n"); + return No_Fault; + case TSDEV_CC_MISC: + //If it is the seventh bit, clear the RTC interrupt + if ((*(uint64_t*) data) & (1<<4)) { + RTCInterrupting = false; + tsunami->intrctrl->clear(0, TheISA::INTLEVEL_IRQ2, 0); + DPRINTF(Tsunami, "clearing rtc interrupt\n"); + misc &= ~(1<<4); + } else panic("TSDEV_CC_MISC write not implemented\n"); + return No_Fault; + 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 No_Fault; + case TSDEV_CC_DIM0: + dim[0] = *(uint64_t*)data; + if (dim[0] & drir) { + dir[0] = dim[0] & drir; + if (!dirInterrupting[0]) { + dirInterrupting[0] = true; + tsunami->intrctrl->post(0, TheISA::INTLEVEL_IRQ1, 0); + DPRINTF(Tsunami, "posting dir interrupt to cpu 0\n"); + } + } + return No_Fault; + case TSDEV_CC_DIM1: + dim[1] = *(uint64_t*)data; + if (dim[1] & drir) { + dir[1] = dim[1] & drir; + if (!dirInterrupting[1]) { + dirInterrupting[1] = true; + tsunami->intrctrl->post(1, TheISA::INTLEVEL_IRQ1, 0); + DPRINTF(Tsunami, "posting dir interrupt to cpu 1\n"); + } + } + return No_Fault; + case TSDEV_CC_DIM2: + dim[2] = *(uint64_t*)data; + if (dim[2] & drir) { + dir[2] = dim[2] & drir; + if (!dirInterrupting[2]) { + dirInterrupting[2] = true; + tsunami->intrctrl->post(2, TheISA::INTLEVEL_IRQ1, 0); + DPRINTF(Tsunami, "posting dir interrupt to cpu 2\n"); + } + } + return No_Fault; + case TSDEV_CC_DIM3: + dim[3] = *(uint64_t*)data; + if ((dim[3] & drir) /*And Not Already Int*/) { + dir[3] = dim[3] & drir; + if (!dirInterrupting[3]) { + dirInterrupting[3] = true; + tsunami->intrctrl->post(3, TheISA::INTLEVEL_IRQ1, 0); + DPRINTF(Tsunami, "posting dir interrupt to cpu 3\n"); + } + } + return No_Fault; + case TSDEV_CC_DIR0: + case TSDEV_CC_DIR1: + case TSDEV_CC_DIR2: + case TSDEV_CC_DIR3: + panic("TSDEV_CC_DIR write not implemented\n"); + return No_Fault; + case TSDEV_CC_DRIR: + panic("TSDEV_CC_DRIR write not implemented\n"); + return No_Fault; + case TSDEV_CC_PRBEN: + panic("TSDEV_CC_PRBEN write not implemented\n"); + return No_Fault; + case TSDEV_CC_IIC0: + case TSDEV_CC_IIC1: + case TSDEV_CC_IIC2: + case TSDEV_CC_IIC3: + panic("TSDEV_CC_IICx write not implemented\n"); + return No_Fault; + case TSDEV_CC_MPR0: + case TSDEV_CC_MPR1: + case TSDEV_CC_MPR2: + case TSDEV_CC_MPR3: + panic("TSDEV_CC_MPRx write not implemented\n"); + return No_Fault; + default: + panic("default in cchip read reached, accessing 0x%x\n"); + } + + break; + case sizeof(uint32_t): + case sizeof(uint16_t): + case sizeof(uint8_t): + default: + panic("invalid access size(?) for tsunami register!\n"); + } + + DPRINTFN("Tsunami ERROR: write daddr=%#x size=%d\n", daddr, req->size); + + return No_Fault; +} + +void +TsunamiCChip::postDRIR(uint64_t bitvector) +{ + drir |= bitvector; + for(int i=0; i < Tsunami::Max_CPUs; i++) { + if (bitvector & dim[i]) { + dir[i] |= bitvector; + if (!dirInterrupting[i]) { + dirInterrupting[i] = true; + tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ1, 0); + DPRINTF(Tsunami, "posting dir interrupt to cpu %d\n",i); + } + } + } +} + +void +TsunamiCChip::clearDRIR(uint64_t bitvector) +{ + drir &= ~bitvector; + for(int i=0; i < Tsunami::Max_CPUs; i++) { + dir[i] &= ~bitvector; + if (!dir[i]) { + dirInterrupting[i] = false; + tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ1, 0); + DPRINTF(Tsunami, "clearing dir interrupt to cpu %d\n", i); + + } + } +} + +void +TsunamiCChip::serialize(std::ostream &os) +{ + // code should be written +} + +void +TsunamiCChip::unserialize(Checkpoint *cp, const std::string §ion) +{ + //code should be written +} + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip) + + SimObjectParam<Tsunami *> tsunami; + SimObjectParam<MemoryController *> mmu; + Param<Addr> addr; + Param<Addr> mask; + +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(mask, "Address Mask") + +END_INIT_SIM_OBJECT_PARAMS(TsunamiCChip) + +CREATE_SIM_OBJECT(TsunamiCChip) +{ + return new TsunamiCChip(getInstanceName(), tsunami, addr, mask, mmu); +} + +REGISTER_SIM_OBJECT("TsunamiCChip", TsunamiCChip) diff --git a/dev/tsunami_cchip.hh b/dev/tsunami_cchip.hh new file mode 100644 index 000000000..16d795afb --- /dev/null +++ b/dev/tsunami_cchip.hh @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2003 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* @file + * Emulation of the Tsunami CChip CSRs + */ + +#ifndef __TSUNAMI_CCHIP_HH__ +#define __TSUNAMI_CCHIP_HH__ + +#include "mem/functional_mem/mmap_device.hh" +#include "dev/tsunami.hh" + +/* + * Tsunami CChip + */ +class TsunamiCChip : public MmapDevice +{ + public: + + protected: + /** + * pointer to the tsunami object. + * This is our access to all the other tsunami + * devices. + */ + Tsunami *tsunami; + + /** + * The dims are device interrupt mask registers. + * One exists for each CPU, the DRIR X DIM = DIR + */ + uint64_t dim[Tsunami::Max_CPUs]; + + /** + * The dirs are device interrupt registers. + * One exists for each CPU, the DRIR X DIM = DIR + */ + uint64_t dir[Tsunami::Max_CPUs]; + bool dirInterrupting[Tsunami::Max_CPUs]; + + /** + * This register contains bits for each PCI interrupt + * that can occur. + */ + uint64_t drir; + + public: + TsunamiCChip(const std::string &name, Tsunami *t, + Addr addr, Addr mask, MemoryController *mmu); + + virtual Fault read(MemReqPtr &req, uint8_t *data); + virtual Fault write(MemReqPtr &req, const uint8_t *data); + + void postDRIR(uint64_t bitvector); + void clearDRIR(uint64_t bitvector); + + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); + + uint64_t misc; + bool RTCInterrupting; +}; + +#endif // __TSUNAMI_CCHIP_HH__ diff --git a/dev/tsunami_io.cc b/dev/tsunami_io.cc new file mode 100644 index 000000000..25323ee14 --- /dev/null +++ b/dev/tsunami_io.cc @@ -0,0 +1,383 @@ +/* + * Copyright (c) 2003 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* @file + * Tsunami I/O including PIC, PIT, RTC, DMA + */ + +#include <sys/time.h> + +#include <deque> +#include <string> +#include <vector> + +#include "base/trace.hh" +#include "cpu/exec_context.hh" +#include "dev/console.hh" +#include "dev/tlaser_clock.hh" +#include "dev/tsunami_io.hh" +#include "dev/tsunamireg.h" +#include "dev/tsunami.hh" +#include "mem/functional_mem/memory_control.hh" +#include "sim/builder.hh" +#include "dev/tsunami_cchip.hh" + +using namespace std; + +#define UNIX_YEAR_OFFSET 52 + +// Timer Event for Periodic interrupt of RTC +TsunamiIO::RTCEvent::RTCEvent(Tsunami* t) + : Event(&mainEventQueue), tsunami(t) +{ + DPRINTF(MC146818, "RTC Event Initilizing\n"); + schedule(curTick + ticksPerSecond/RTC_RATE); +} + +void +TsunamiIO::RTCEvent::process() +{ + DPRINTF(MC146818, "RTC Timer Interrupt\n"); + schedule(curTick + ticksPerSecond/RTC_RATE); + //Actually interrupt the processor here + if (!tsunami->cchip->RTCInterrupting) { + tsunami->cchip->misc |= 1 << 7; + tsunami->cchip->RTCInterrupting = true; + tsunami->intrctrl->post(0, TheISA::INTLEVEL_IRQ2, 0); + } +} + +const char * +TsunamiIO::RTCEvent::description() +{ + return "tsunami RTC 1024Hz interrupt"; +} + +// Timer Event for PIT Timers +TsunamiIO::ClockEvent::ClockEvent() + : Event(&mainEventQueue) +{ + DPRINTF(Tsunami, "Clock Event Initilizing\n"); + mode = 0; +} + +void +TsunamiIO::ClockEvent::process() +{ + DPRINTF(Tsunami, "Timer Interrupt\n"); + if (mode == 0) + status = 0x20; // set bit that linux is looking for + else + schedule(curTick + interval); +} + +void +TsunamiIO::ClockEvent::Program(int count) +{ + DPRINTF(Tsunami, "Timer set to curTick + %d\n", count); + // should be count * (cpufreq/pitfreq) + interval = count * ticksPerSecond/1193180UL; + schedule(curTick + interval); + status = 0; +} + +const char * +TsunamiIO::ClockEvent::description() +{ + return "tsunami 8254 Interval timer"; +} + +void +TsunamiIO::ClockEvent::ChangeMode(uint8_t md) +{ + mode = md; +} + +uint8_t +TsunamiIO::ClockEvent::Status() +{ + return status; +} + +TsunamiIO::TsunamiIO(const string &name, Tsunami *t, time_t init_time, + Addr addr, Addr mask, MemoryController *mmu) + : MmapDevice(name, addr, mask, mmu), tsunami(t), rtc(t) +{ + // set the back pointer from tsunami to myself + tsunami->io = this; + + timerData = 0; + set_time(init_time == 0 ? time(NULL) : init_time); + uip = 1; + picr = 0; + picInterrupting = false; +} + +void +TsunamiIO::set_time(time_t t) +{ + gmtime_r(&t, &tm); + DPRINTFN("Real-time clock set to %s", asctime(&tm)); +} + +Fault +TsunamiIO::read(MemReqPtr &req, uint8_t *data) +{ + DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n", + req->vaddr, req->size, req->vaddr & 0xfff); + + Addr daddr = (req->paddr & addr_mask); +// ExecContext *xc = req->xc; +// int cpuid = xc->cpu_id; + + switch(req->size) { + case sizeof(uint8_t): + switch(daddr) { + case TSDEV_TMR_CTL: + *(uint8_t*)data = timer2.Status(); + return No_Fault; + case TSDEV_RTC_DATA: + switch(RTCAddress) { + case RTC_CONTROL_REGISTERA: + *(uint8_t*)data = uip << 7 | 0x26; + uip = !uip; + return No_Fault; + case RTC_CONTROL_REGISTERB: + // DM and 24/12 and UIE + *(uint8_t*)data = 0x46; + return No_Fault; + case RTC_CONTROL_REGISTERC: + // If we want to support RTC user access in linux + // This won't work, but for now it's fine + *(uint8_t*)data = 0x00; + return No_Fault; + case RTC_CONTROL_REGISTERD: + panic("RTC Control Register D not implemented"); + case RTC_SECOND: + *(uint8_t *)data = tm.tm_sec; + return No_Fault; + case RTC_MINUTE: + *(uint8_t *)data = tm.tm_min; + return No_Fault; + case RTC_HOUR: + *(uint8_t *)data = tm.tm_hour; + return No_Fault; + case RTC_DAY_OF_WEEK: + *(uint8_t *)data = tm.tm_wday; + return No_Fault; + case RTC_DAY_OF_MONTH: + *(uint8_t *)data = tm.tm_mday; + case RTC_MONTH: + *(uint8_t *)data = tm.tm_mon + 1; + return No_Fault; + case RTC_YEAR: + *(uint8_t *)data = tm.tm_year - UNIX_YEAR_OFFSET; + return No_Fault; + default: + panic("Unknown RTC Address\n"); + } + + default: + panic("I/O Read - va%#x size %d\n", req->vaddr, req->size); + } + case sizeof(uint16_t): + case sizeof(uint32_t): + case sizeof(uint64_t): + default: + panic("I/O Read - invalid size - va %#x size %d\n", + req->vaddr, req->size); + } + panic("I/O Read - va%#x size %d\n", req->vaddr, req->size); + + return No_Fault; +} + +Fault +TsunamiIO::write(MemReqPtr &req, const uint8_t *data) +{ + uint8_t dt = *(uint8_t*)data; + uint64_t dt64 = dt; + + DPRINTF(Tsunami, "io write - va=%#x size=%d IOPort=%#x Data=%#x\n", + req->vaddr, req->size, req->vaddr & 0xfff, dt64); + + Addr daddr = (req->paddr & addr_mask); + + 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(uint64_t(1) << 55); + DPRINTF(Tsunami, "posting pic interrupt to cchip\n"); + } + return No_Fault; + case TSDEV_PIC2_MASK: + mask2 = *(uint8_t*)data; + //PIC2 Not implemented to interrupt + return No_Fault; + case TSDEV_DMA1_RESET: + return No_Fault; + case TSDEV_DMA2_RESET: + return No_Fault; + case TSDEV_DMA1_MODE: + mode1 = *(uint8_t*)data; + return No_Fault; + case TSDEV_DMA2_MODE: + mode2 = *(uint8_t*)data; + return No_Fault; + case TSDEV_DMA1_MASK: + case TSDEV_DMA2_MASK: + return No_Fault; + case TSDEV_TMR_CTL: + return No_Fault; + case TSDEV_TMR2_CTL: + if ((*(uint8_t*)data & 0x30) != 0x30) + panic("Only L/M write supported\n"); + + switch(*(uint8_t*)data >> 6) { + case 0: + timer0.ChangeMode((*(uint8_t*)data & 0xF) >> 1); + break; + case 2: + timer2.ChangeMode((*(uint8_t*)data & 0xF) >> 1); + break; + default: + panic("Read Back Command not implemented\n"); + } + return No_Fault; + case TSDEV_TMR2_DATA: + /* two writes before we actually start the Timer + so I set a flag in the timerData */ + if(timerData & 0x1000) { + timerData &= 0x1000; + timerData += *(uint8_t*)data << 8; + timer2.Program(timerData); + } else { + timerData = *(uint8_t*)data; + timerData |= 0x1000; + } + return No_Fault; + case TSDEV_TMR0_DATA: + /* two writes before we actually start the Timer + so I set a flag in the timerData */ + if(timerData & 0x1000) { + timerData &= 0x1000; + timerData += *(uint8_t*)data << 8; + timer0.Program(timerData); + } else { + timerData = *(uint8_t*)data; + timerData |= 0x1000; + } + return No_Fault; + case TSDEV_RTC_ADDR: + RTCAddress = *(uint8_t*)data; + return No_Fault; + case TSDEV_RTC_DATA: + panic("RTC Write not implmented (rtc.o won't work)\n"); + default: + panic("I/O Write - va%#x size %d\n", req->vaddr, req->size); + } + case sizeof(uint16_t): + case sizeof(uint32_t): + case sizeof(uint64_t): + default: + panic("I/O Write - invalid size - va %#x size %d\n", + req->vaddr, req->size); + } + + + return No_Fault; +} + +void +TsunamiIO::postPIC(uint8_t bitvector) +{ + //PIC2 Is not implemented, because nothing of interest there + picr |= bitvector; + if ((picr & mask1) && !picInterrupting) { + picInterrupting = true; + tsunami->cchip->postDRIR(uint64_t(1) << 55); + DPRINTF(Tsunami, "posting pic interrupt to cchip\n"); + } +} + +void +TsunamiIO::clearPIC(uint8_t bitvector) +{ + //PIC2 Is not implemented, because nothing of interest there + picr &= ~bitvector; + if (!(picr & mask1)) { + picInterrupting = false; + tsunami->cchip->clearDRIR(uint64_t(1) << 55); + DPRINTF(Tsunami, "clearing pic interrupt to cchip\n"); + } +} + +void +TsunamiIO::serialize(std::ostream &os) +{ + // code should be written +} + +void +TsunamiIO::unserialize(Checkpoint *cp, const std::string §ion) +{ + //code should be written +} + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO) + + SimObjectParam<Tsunami *> tsunami; + Param<time_t> time; + SimObjectParam<MemoryController *> mmu; + Param<Addr> addr; + Param<Addr> mask; + +END_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO) + +BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiIO) + + INIT_PARAM(tsunami, "Tsunami"), + INIT_PARAM_DFLT(time, "System time to use " + "(0 for actual time, default is 1/1/06", ULL(1136073600)), + INIT_PARAM(mmu, "Memory Controller"), + INIT_PARAM(addr, "Device Address"), + INIT_PARAM(mask, "Address Mask") + +END_INIT_SIM_OBJECT_PARAMS(TsunamiIO) + +CREATE_SIM_OBJECT(TsunamiIO) +{ + return new TsunamiIO(getInstanceName(), tsunami, time, addr, + mask, mmu); +} + +REGISTER_SIM_OBJECT("TsunamiIO", TsunamiIO) diff --git a/dev/tsunami_io.hh b/dev/tsunami_io.hh new file mode 100644 index 000000000..aa77645f3 --- /dev/null +++ b/dev/tsunami_io.hh @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2003 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* @file + * Tsunami Fake I/O Space mapping including RTC/timer interrupts + */ + +#ifndef __TSUNAMI_DMA_HH__ +#define __TSUNAMI_DMA_HH__ + +#define RTC_RATE 1024 + +#include "mem/functional_mem/mmap_device.hh" +#include "dev/tsunami.hh" + +/* + * Tsunami I/O device + */ +class TsunamiIO : public MmapDevice +{ + + private: + struct tm tm; + + // In Tsunami RTC only has two i/o ports + // one for data and one for address, so you + // write the address and then read/write the data + uint8_t RTCAddress; + + protected: + + class ClockEvent : public Event + { + protected: + Tick interval; + uint8_t mode; + uint8_t status; + + public: + ClockEvent(); + + virtual void process(); + virtual const char *description(); + void Program(int count); + void ChangeMode(uint8_t mode); + uint8_t Status(); + + }; + + class RTCEvent : public Event + { + protected: + Tsunami* tsunami; + public: + RTCEvent(Tsunami* t); + + virtual void process(); + virtual const char *description(); + }; + + uint8_t uip; + + uint8_t mask1; + uint8_t mask2; + uint8_t mode1; + uint8_t mode2; + + uint8_t picr; //Raw PIC interrput register, before masking + bool picInterrupting; + + Tsunami *tsunami; + + /* + * This timer is initilized, but after I wrote the code + * it doesn't seem to be used again, and best I can tell + * it too is not connected to any interrupt port + */ + ClockEvent timer0; + + /* + * This timer is used to control the speaker, which + * we normally could care less about, however it is + * also used to calculated the clockspeed and hense + * bogomips which is kinda important to the scheduler + * so we need to implemnt it although after boot I can't + * imagine we would be playing with the PC speaker much + */ + ClockEvent timer2; + + RTCEvent rtc; + + uint32_t timerData; + + + public: + uint32_t frequency() const { return RTC_RATE; } + + TsunamiIO(const std::string &name, Tsunami *t, time_t init_time, + Addr addr, Addr mask, MemoryController *mmu); + + void set_time(time_t t); + + virtual Fault read(MemReqPtr &req, uint8_t *data); + virtual Fault write(MemReqPtr &req, const uint8_t *data); + + void postPIC(uint8_t bitvector); + void clearPIC(uint8_t bitvector); + + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); +}; + +#endif // __TSUNAMI_IO_HH__ diff --git a/dev/tsunami_pchip.cc b/dev/tsunami_pchip.cc new file mode 100644 index 000000000..61f126c8b --- /dev/null +++ b/dev/tsunami_pchip.cc @@ -0,0 +1,260 @@ +/* $Id$ */ + +/* @file + * Tsunami PChip (pci) + */ + +#include <deque> +#include <string> +#include <vector> + +#include "base/trace.hh" +#include "cpu/exec_context.hh" +#include "dev/console.hh" +#include "dev/etherdev.hh" +#include "dev/scsi_ctrl.hh" +#include "dev/tlaser_clock.hh" +#include "dev/tsunami_pchip.hh" +#include "dev/tsunamireg.h" +#include "dev/tsunami.hh" +#include "mem/functional_mem/memory_control.hh" +#include "sim/builder.hh" +#include "sim/system.hh" + +using namespace std; + +TsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, + Addr addr, Addr mask, MemoryController *mmu) + : MmapDevice(name, addr, mask, mmu), tsunami(t) +{ + wsba0 = 0; + wsba1 = 0; + wsba2 = 0; + wsba3 = 0; + wsm0 = 0; + wsm1 = 0; + wsm2 = 0; + wsm3 = 0; + tba0 = 0; + tba1 = 0; + tba2 = 0; + tba3 = 0; + + //Set back pointer in tsunami + tsunami->pchip = this; +} + +Fault +TsunamiPChip::read(MemReqPtr &req, uint8_t *data) +{ + DPRINTF(Tsunami, "read va=%#x size=%d\n", + req->vaddr, req->size); + + Addr daddr = (req->paddr & addr_mask) >> 6; +// ExecContext *xc = req->xc; +// int cpuid = xc->cpu_id; + + switch (req->size) { + + case sizeof(uint64_t): + switch(daddr) { + case TSDEV_PC_WSBA0: + *(uint64_t*)data = wsba0; + return No_Fault; + case TSDEV_PC_WSBA1: + *(uint64_t*)data = wsba1; + return No_Fault; + case TSDEV_PC_WSBA2: + *(uint64_t*)data = wsba2; + return No_Fault; + case TSDEV_PC_WSBA3: + *(uint64_t*)data = wsba3; + return No_Fault; + case TSDEV_PC_WSM0: + *(uint64_t*)data = wsm0; + return No_Fault; + case TSDEV_PC_WSM1: + *(uint64_t*)data = wsm1; + return No_Fault; + case TSDEV_PC_WSM2: + *(uint64_t*)data = wsm2; + return No_Fault; + case TSDEV_PC_WSM3: + *(uint64_t*)data = wsm3; + return No_Fault; + case TSDEV_PC_TBA0: + *(uint64_t*)data = tba0; + return No_Fault; + case TSDEV_PC_TBA1: + *(uint64_t*)data = tba1; + return No_Fault; + case TSDEV_PC_TBA2: + *(uint64_t*)data = tba2; + return No_Fault; + case TSDEV_PC_TBA3: + *(uint64_t*)data = tba3; + return No_Fault; + case TSDEV_PC_PCTL: + // might want to change the clock?? + *(uint64_t*)data = 0x00; // try this + return No_Fault; + case TSDEV_PC_PLAT: + panic("PC_PLAT not implemented\n"); + case TSDEV_PC_RES: + panic("PC_RES not implemented\n"); + case TSDEV_PC_PERROR: + panic("PC_PERROR not implemented\n"); + 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: + *(uint64_t*)data = 0x00; // shouldn't be readable, but linux + return No_Fault; + 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 PChip ERROR: read daddr=%#x size=%d\n", daddr, req->size); + + return No_Fault; +} + +Fault +TsunamiPChip::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; + + switch (req->size) { + + case sizeof(uint64_t): + switch(daddr) { + case TSDEV_PC_WSBA0: + wsba0 = *(uint64_t*)data; + return No_Fault; + case TSDEV_PC_WSBA1: + wsba1 = *(uint64_t*)data; + return No_Fault; + case TSDEV_PC_WSBA2: + wsba2 = *(uint64_t*)data; + return No_Fault; + case TSDEV_PC_WSBA3: + wsba3 = *(uint64_t*)data; + return No_Fault; + case TSDEV_PC_WSM0: + wsm0 = *(uint64_t*)data; + return No_Fault; + case TSDEV_PC_WSM1: + wsm1 = *(uint64_t*)data; + return No_Fault; + case TSDEV_PC_WSM2: + wsm2 = *(uint64_t*)data; + return No_Fault; + case TSDEV_PC_WSM3: + wsm3 = *(uint64_t*)data; + return No_Fault; + case TSDEV_PC_TBA0: + tba0 = *(uint64_t*)data; + return No_Fault; + case TSDEV_PC_TBA1: + tba1 = *(uint64_t*)data; + return No_Fault; + case TSDEV_PC_TBA2: + tba2 = *(uint64_t*)data; + return No_Fault; + case TSDEV_PC_TBA3: + tba3 = *(uint64_t*)data; + return No_Fault; + case TSDEV_PC_PCTL: + // might want to change the clock?? + //*(uint64_t*)data; // try this + return No_Fault; + case TSDEV_PC_PLAT: + panic("PC_PLAT not implemented\n"); + case TSDEV_PC_RES: + panic("PC_RES not implemented\n"); + case TSDEV_PC_PERROR: + panic("PC_PERROR not implemented\n"); + 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 No_Fault; // 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 No_Fault; +} + +void +TsunamiPChip::serialize(std::ostream &os) +{ + // code should be written +} + +void +TsunamiPChip::unserialize(Checkpoint *cp, const std::string §ion) +{ + //code should be written +} + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip) + + SimObjectParam<Tsunami *> tsunami; + SimObjectParam<MemoryController *> mmu; + Param<Addr> addr; + Param<Addr> mask; + +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(mask, "Address Mask") + +END_INIT_SIM_OBJECT_PARAMS(TsunamiPChip) + +CREATE_SIM_OBJECT(TsunamiPChip) +{ + return new TsunamiPChip(getInstanceName(), tsunami, addr, mask, mmu); +} + +REGISTER_SIM_OBJECT("TsunamiPChip", TsunamiPChip) diff --git a/dev/tsunami_pchip.hh b/dev/tsunami_pchip.hh new file mode 100644 index 000000000..b00866e03 --- /dev/null +++ b/dev/tsunami_pchip.hh @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2003 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* @file + * Tsunami PChip + */ + +#ifndef __TSUNAMI_PCHIP_HH__ +#define __TSUNAMI_PCHIP_HH__ + +#include "mem/functional_mem/mmap_device.hh" +#include "dev/tsunami.hh" + +/* + * Tsunami PChip + */ +class TsunamiPChip : public MmapDevice +{ + public: + + protected: + Tsunami *tsunami; + + uint64_t wsba0; + uint64_t wsba1; + uint64_t wsba2; + uint64_t wsba3; + uint64_t wsm0; + uint64_t wsm1; + uint64_t wsm2; + uint64_t wsm3; + uint64_t tba0; + uint64_t tba1; + uint64_t tba2; + uint64_t tba3; + + + public: + TsunamiPChip(const std::string &name, Tsunami *t, + Addr addr, Addr mask, MemoryController *mmu); + + virtual Fault read(MemReqPtr &req, uint8_t *data); + virtual Fault write(MemReqPtr &req, const uint8_t *data); + + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); +}; + +#endif // __TSUNAMI_PCHIP_HH__ diff --git a/dev/tsunami_uart.cc b/dev/tsunami_uart.cc new file mode 100644 index 000000000..0a0b5ffef --- /dev/null +++ b/dev/tsunami_uart.cc @@ -0,0 +1,219 @@ +/* $Id$ */ + +/* @file + * Tsunami UART + */ + +/* + * Copyright (C) 1998 by the Board of Trustees + * of Leland Stanford Junior University. + * Copyright (C) 1998 Digital Equipment Corporation + * + * This file is part of the SimOS distribution. + * See LICENSE file for terms of the license. + * + */ + +#include <string> +#include <vector> + +#include "base/inifile.hh" +#include "base/str.hh" // for to_number +#include "base/trace.hh" +#include "dev/console.hh" +#include "dev/tsunami_uart.hh" +#include "mem/functional_mem/memory_control.hh" +#include "sim/builder.hh" +#include "targetarch/ev5.hh" + +using namespace std; + +#define CONS_INT_TX 0x01 // interrupt enable / state bits +#define CONS_INT_RX 0x02 + +TsunamiUart::TsunamiUart(const string &name, SimConsole *c, + Addr addr, Addr mask, MemoryController *mmu) + : MmapDevice(name, addr, mask, mmu), + cons(c), status_store(0), valid_char(false) +{ + IER = 0; +} + +Fault +TsunamiUart::read(MemReqPtr &req, uint8_t *data) +{ + Addr daddr = req->paddr & addr_mask; + DPRINTF(TsunamiUart, " read register %#x\n", daddr); + + switch (req->size) { + case sizeof(uint64_t): + *(uint64_t *)data = 0; + break; + case sizeof(uint32_t): + *(uint32_t *)data = 0; + break; + case sizeof(uint16_t): + *(uint16_t *)data = 0; + break; + case sizeof(uint8_t): + *(uint8_t *)data = 0; + break; + } + + switch (daddr) { + case 0xD: // Status Register + { + int status = cons->intStatus(); + if (!valid_char) { + valid_char = cons->in(next_char); + if (!valid_char) + status &= ~CONS_INT_RX; + } else { + status |= CONS_INT_RX; + } + + if (status_store == 3) { + // RR3 stuff? Don't really understand it, btw + status_store = 0; + if (status & CONS_INT_TX) { + *data = (1 << 4); + return No_Fault; + } else if (status & CONS_INT_RX) { + *data = (1 << 5); + return No_Fault; + } else { + DPRINTF(TsunamiUart, "spurious read\n"); + return No_Fault; + } + } else { + int reg = (1 << 2) | (1 << 5) | (1 << 6); + if (status & CONS_INT_RX) + reg |= (1 << 0); + *data = reg; + return No_Fault; + } + break; + } + + case 0x8: // Data register (RX) +// if (!valid_char) +// panic("Invalid character"); + + DPRINTF(TsunamiUart, "read data register \'%c\' %#02x\n", + isprint(next_char) ? next_char : ' ', next_char); + + *data = next_char; + valid_char = false; + return No_Fault; + + case 0x9: // Interrupt Enable Register + // This is the lovely way linux checks there is actually a serial + // port at the desired address + if (IER == 0) + *data = 0; + else if (IER == 0x0F) + *data = 0x0F; + else + *data = 0; + return No_Fault; + case 0xA: + //*data = 2<<6; // This means a 8250 serial port, do we want a 16550? + *data = 0; // This means a 8250 serial port, do we want a 16550? + return No_Fault; + } + *data = 0; + // panic("%s: read daddr=%#x type=read *data=%#x\n", name(), daddr, *data); + + return No_Fault; +} + +Fault +TsunamiUart::write(MemReqPtr &req, const uint8_t *data) +{ + Addr daddr = req->paddr & addr_mask; + + DPRINTF(TsunamiUart, " write register %#x value %#x\n", daddr, *(uint8_t*)data); + switch (daddr) { + case 0xb: + status_store = *data; + switch (*data) { + case 0x03: // going to read RR3 + return No_Fault; + + case 0x28: // Ack of TX + { + if ((cons->intStatus() & CONS_INT_TX) == 0) + panic("Ack of transmit, though there was no interrupt"); + + cons->clearInt(CONS_INT_TX); + return No_Fault; + } + + case 0x00: + case 0x01: + case 0x12: + // going to write data??? + return No_Fault; + + default: + DPRINTF(TsunamiUart, "writing status register %#x \n", + *(uint8_t *)data); + return No_Fault; + } + + case 0x8: // Data register (TX) + cons->out(*(uint64_t *)data); + return No_Fault; + case 0x9: // DLM + DPRINTF(TsunamiUart, "writing to DLM/IER %#x\n", *(uint8_t*)data); + IER = *(uint8_t*)data; + return No_Fault; + case 0xc: // MCR + DPRINTF(TsunamiUart, "writing to MCR %#x\n", *(uint8_t*)data); + return No_Fault; + + } + + return No_Fault; +} + +void +TsunamiUart::serialize(ostream &os) +{ + SERIALIZE_SCALAR(status_store); + SERIALIZE_SCALAR(next_char); + SERIALIZE_SCALAR(valid_char); +} + +void +TsunamiUart::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_SCALAR(status_store); + UNSERIALIZE_SCALAR(next_char); + UNSERIALIZE_SCALAR(valid_char); +} + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiUart) + + SimObjectParam<SimConsole *> console; + SimObjectParam<MemoryController *> mmu; + Param<Addr> addr; + Param<Addr> mask; + +END_DECLARE_SIM_OBJECT_PARAMS(TsunamiUart) + +BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiUart) + + INIT_PARAM(console, "The console"), + INIT_PARAM(mmu, "Memory Controller"), + INIT_PARAM(addr, "Device Address"), + INIT_PARAM(mask, "Address Mask") + +END_INIT_SIM_OBJECT_PARAMS(TsunamiUart) + +CREATE_SIM_OBJECT(TsunamiUart) +{ + return new TsunamiUart(getInstanceName(), console, addr, mask, mmu); +} + +REGISTER_SIM_OBJECT("TsunamiUart", TsunamiUart) diff --git a/dev/tsunami_uart.hh b/dev/tsunami_uart.hh new file mode 100644 index 000000000..02d2f4543 --- /dev/null +++ b/dev/tsunami_uart.hh @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2003 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* @file + * Tsunami UART + */ + +#ifndef __TSUNAMI_UART_HH__ +#define __TSUNAMI_UART_HH__ + +#include "mem/functional_mem/mmap_device.hh" + +class SimConsole; + +/* + * Tsunami UART + */ +class TsunamiUart : public MmapDevice +{ + protected: + SimConsole *cons; + int status_store; + uint8_t next_char; + bool valid_char; + uint8_t IER; + + public: + TsunamiUart(const std::string &name, SimConsole *c, + Addr addr, Addr mask, MemoryController *mmu); + + Fault read(MemReqPtr &req, uint8_t *data); + Fault write(MemReqPtr &req, const uint8_t *data); + + + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); +}; + +#endif // __TSUNAMI_UART_HH__ diff --git a/dev/tsunamireg.h b/dev/tsunamireg.h new file mode 100644 index 000000000..c74279ecf --- /dev/null +++ b/dev/tsunamireg.h @@ -0,0 +1,110 @@ + +#ifndef __TSUNAMIREG_H__ +#define __TSUNAMIREG_H__ + +#define ALPHA_K0SEG_BASE 0xfffffc0000000000 + +// CChip Registers +#define TSDEV_CC_CSR 0x00 +#define TSDEV_CC_MTR 0x01 +#define TSDEV_CC_MISC 0x02 + +#define TSDEV_CC_AAR0 0x04 +#define TSDEV_CC_AAR1 0x05 +#define TSDEV_CC_AAR2 0x06 +#define TSDEV_CC_AAR3 0x07 +#define TSDEV_CC_DIM0 0x08 +#define TSDEV_CC_DIM1 0x09 +#define TSDEV_CC_DIR0 0x0A +#define TSDEV_CC_DIR1 0x0B +#define TSDEV_CC_DRIR 0x0C +#define TSDEV_CC_PRBEN 0x0D +#define TSDEV_CC_IIC0 0x0E +#define TSDEV_CC_IIC1 0x0F +#define TSDEV_CC_MPR0 0x10 +#define TSDEV_CC_MPR1 0x11 +#define TSDEV_CC_MPR2 0x12 +#define TSDEV_CC_MPR3 0x13 + +#define TSDEV_CC_DIM2 0x18 +#define TSDEV_CC_DIM3 0x19 +#define TSDEV_CC_DIR2 0x1A +#define TSDEV_CC_DIR3 0x1B +#define TSDEV_CC_IIC2 0x1C +#define TSDEV_CC_IIC3 0x1D + + +// PChip Registers +#define TSDEV_PC_WSBA0 0x00 +#define TSDEV_PC_WSBA1 0x01 +#define TSDEV_PC_WSBA2 0x02 +#define TSDEV_PC_WSBA3 0x03 +#define TSDEV_PC_WSM0 0x04 +#define TSDEV_PC_WSM1 0x05 +#define TSDEV_PC_WSM2 0x06 +#define TSDEV_PC_WSM3 0x07 +#define TSDEV_PC_TBA0 0x08 +#define TSDEV_PC_TBA1 0x09 +#define TSDEV_PC_TBA2 0x0A +#define TSDEV_PC_TBA3 0x0B +#define TSDEV_PC_PCTL 0x0C +#define TSDEV_PC_PLAT 0x0D +#define TSDEV_PC_RES 0x0E +#define TSDEV_PC_PERROR 0x0F +#define TSDEV_PC_PERRMASK 0x10 +#define TSDEV_PC_PERRSET 0x11 +#define TSDEV_PC_TLBIV 0x12 +#define TSDEV_PC_TLBIA 0x13 +#define TSDEV_PC_PMONCTL 0x14 +#define TSDEV_PC_PMONCNT 0x15 + +#define TSDEV_PC_SPST 0x20 + + +// DChip Registers +#define TSDEV_DC_DSC 0x20 +#define TSDEV_DC_STR 0x21 +#define TSDEV_DC_DREV 0x22 +#define TSDEV_DC_DSC2 0x23 + +// I/O Ports +#define TSDEV_PIC1_MASK 0x21 +#define TSDEV_PIC2_MASK 0xA1 +#define TSDEV_DMA1_RESET 0x0D +#define TSDEV_DMA2_RESET 0xDA +#define TSDEV_DMA1_MODE 0x0B +#define TSDEV_DMA2_MODE 0xD6 +#define TSDEV_DMA1_MASK 0x0A +#define TSDEV_DMA2_MASK 0xD4 +#define TSDEV_TMR_CTL 0x61 +#define TSDEV_TMR2_CTL 0x43 +#define TSDEV_TMR2_DATA 0x42 +#define TSDEV_TMR0_DATA 0x40 + +#define TSDEV_RTC_ADDR 0x70 +#define TSDEV_RTC_DATA 0x71 + +// RTC defines +#define RTC_SECOND 0 // second of minute [0..59] +#define RTC_SECOND_ALARM 1 // seconds to alarm +#define RTC_MINUTE 2 // minute of hour [0..59] +#define RTC_MINUTE_ALARM 3 // minutes to alarm +#define RTC_HOUR 4 // hour of day [0..23] +#define RTC_HOUR_ALARM 5 // hours to alarm +#define RTC_DAY_OF_WEEK 6 // day of week [1..7] +#define RTC_DAY_OF_MONTH 7 // day of month [1..31] +#define RTC_MONTH 8 // month of year [1..12] +#define RTC_YEAR 9 // year [00..99] +#define RTC_CONTROL_REGISTERA 10 // control register A +#define RTC_CONTROL_REGISTERB 11 // control register B +#define RTC_CONTROL_REGISTERC 12 // control register C +#define RTC_CONTROL_REGISTERD 13 // control register D +#define RTC_REGNUMBER_RTC_CR1 0x6A // control register 1 + +#define PCHIP_PCI0_MEMORY 0x10000000000 +#define PCHIP_PCI0_IO 0x101FC000000 +#define TSUNAMI_PCI0_MEMORY ALPHA_K0SEG_BASE + PCHIP_PCI0_MEMORY +#define TSUNAMI_PCI0_IO ALPHA_K0SEG_BASE + PCHIP_PCI0_IO + + +#endif // __TSUNAMIREG_H__ |