summaryrefslogtreecommitdiff
path: root/dev
diff options
context:
space:
mode:
Diffstat (limited to 'dev')
-rw-r--r--dev/alpha_console.cc12
-rw-r--r--dev/alpha_console.hh9
-rw-r--r--dev/baddev.cc68
-rw-r--r--dev/baddev.hh65
-rw-r--r--dev/console.cc4
-rw-r--r--dev/pciconfigall.cc190
-rw-r--r--dev/pciconfigall.hh91
-rw-r--r--dev/pcidev.cc369
-rw-r--r--dev/pcidev.hh98
-rw-r--r--dev/platform.hh59
-rw-r--r--dev/tsunami.cc93
-rw-r--r--dev/tsunami.hh108
-rw-r--r--dev/tsunami_cchip.cc312
-rw-r--r--dev/tsunami_cchip.hh90
-rw-r--r--dev/tsunami_io.cc383
-rw-r--r--dev/tsunami_io.hh138
-rw-r--r--dev/tsunami_pchip.cc260
-rw-r--r--dev/tsunami_pchip.hh74
-rw-r--r--dev/tsunami_uart.cc219
-rw-r--r--dev/tsunami_uart.hh64
-rw-r--r--dev/tsunamireg.h110
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 &section)
+{
+ //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 &section);
+
+};
+
+#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 &section)
+{
+ 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 &section);
+};
+
+#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 &section)
+{
+ 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 &section);
+};
+
+#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 &section)
+{
+ //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 &section);
+
+ 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 &section)
+{
+ //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 &section);
+};
+
+#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 &section)
+{
+ //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 &section);
+};
+
+#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 &section)
+{
+ 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 &section);
+};
+
+#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__