#include "mem/functional_mem/memory_control.hh"
 #include "sim/builder.hh"
 #include "targetarch/ev5.hh"
+#include "dev/platform.hh"
 
 using namespace std;
 
 #if TRACING_ON == 1
       linebuf(16384),
 #endif
-      _status(0), _enable(0), intr(NULL)
+      _status(0), _enable(0), intr(NULL), platform(NULL)
 {
     if (!file.empty())
         outfile = new ofstream(file.c_str());
 {
     int old = _status;
     _status &= ~i;
-    if (MaskStatus(old, _enable) != MaskStatus(_status, _enable) && intr)
-        intr->clear(TheISA::INTLEVEL_IRQ0);
+    //if (MaskStatus(old, _enable) != MaskStatus(_status, _enable) && intr)
+        platform->clearConsoleInt();
 
     return old;
 }
 void
 SimConsole::raiseInt(int i)
 {
-    int old = _status;
+    //int old = _status;
     _status |= i;
-    if (MaskStatus(old, _enable) != MaskStatus(_status, _enable) && intr)
-        intr->post(TheISA::INTLEVEL_IRQ0);
+    //if (MaskStatus(old, _enable) != MaskStatus(_status, _enable) && intr)
+        platform->postConsoleInt();
 }
 
 void
     old = _enable;
     _enable |= bits;
 
-    if (MaskStatus(_status, old) != MaskStatus(_status, _enable) && intr) {
+    //if (MaskStatus(_status, old) != MaskStatus(_status, _enable) && intr) {
+    if (intr) {
         if (MaskStatus(_status, _enable))
-            intr->post(TheISA::INTLEVEL_IRQ0);
+            platform->postConsoleInt();
         else
-            intr->clear(TheISA::INTLEVEL_IRQ0);
+            platform->clearConsoleInt();
     }
 }
 
+void
+SimConsole::setPlatform(Platform *p)
+{
+    platform = p;
+    platform->cons = this;
+}
 
 void
 SimConsole::serialize(ostream &os)
 
     SimObjectParam<ConsoleListener *> listener;
     SimObjectParam<IntrControl *> intr_control;
+    SimObjectParam<Platform *> platform;
     Param<string> output;
     Param<bool> append_name;
     Param<int> number;
 
     INIT_PARAM(listener, "console listener"),
     INIT_PARAM(intr_control, "interrupt controller"),
+    INIT_PARAM(platform, "platform"),
     INIT_PARAM_DFLT(output, "file to dump output to", ""),
     INIT_PARAM_DFLT(append_name, "append name() to filename", true),
     INIT_PARAM_DFLT(number, "console number", 0)
     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)->setPlatform(platform);
+    //((SimConsole *)console)->setInt(SimConsole::TransmitInterrupt |
+    //                                SimConsole::ReceiveInterrupt);
 
     return console;
 }
 
 
     // interrupt handle
     IntrControl *intr;
+    // Platform so we can post interrupts
+    Platform    *platform;
 
   public:
     /////////////////
     void initInt(IntrControl *i);
     void setInt(int bits);
 
+    void setPlatform(Platform *p);
+
     virtual void serialize(std::ostream &os);
     virtual void unserialize(Checkpoint *cp, const std::string §ion);
 };
 
--- /dev/null
+/*
+ * 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 "dev/platform.hh"
+#include "sim/builder.hh"
+#include "sim/sim_exit.hh"
+
+using namespace std;
+
+DEFINE_SIM_OBJECT_CLASS_NAME("Platform", Platform)
+
 
     int interrupt_frequency;
 
   public:
-    Platform(const std::string &name, SimConsole *con, IntrControl *intctrl,
+    Platform(const std::string &name, IntrControl *intctrl,
              PciConfigAll *pci, int intrFreq)
-        : SimObject(name), intrctrl(intctrl), cons(con), pciconfig(pci),
+        : SimObject(name), intrctrl(intctrl), pciconfig(pci),
           interrupt_frequency(intrFreq) {}
+    virtual ~Platform() {}
+    virtual void postConsoleInt() = 0;
+    virtual void clearConsoleInt() = 0;
 };
 
 #endif // __PLATFORM_HH_
 
 #include "dev/tlaser_clock.hh"
 #include "dev/tsunami_cchip.hh"
 #include "dev/tsunami_pchip.hh"
+#include "dev/tsunami_io.hh"
 #include "dev/tsunami.hh"
 #include "dev/pciconfigall.hh"
 #include "sim/builder.hh"
 
 using namespace std;
 
-Tsunami::Tsunami(const string &name, System *s, SimConsole *con,
+Tsunami::Tsunami(const string &name, System *s,
                  IntrControl *ic, PciConfigAll *pci, int intr_freq)
-    : Platform(name, con, ic, pci, intr_freq), system(s)
+    : Platform(name, ic, pci, intr_freq), system(s)
 {
     // set the back pointer from the system to myself
     system->platform = this;
         intr_sum_type[i] = 0;
 }
 
+void
+Tsunami::postConsoleInt()
+{
+    io->postPIC(0x10);
+}
+
+void
+Tsunami::clearConsoleInt()
+{
+    io->clearPIC(0x10);
+}
+
 void
 Tsunami::serialize(std::ostream &os)
 {
 
 CREATE_SIM_OBJECT(Tsunami)
 {
-    return new Tsunami(getInstanceName(), system, cons, intrctrl, pciconfig,
+    return new Tsunami(getInstanceName(), system, intrctrl, pciconfig,
                        interrupt_frequency);
 }
 
 
       * @param intrcontrol pointer to the interrupt controller
       * @param intrFreq frequency that interrupts happen
       */
-    Tsunami(const std::string &name, System *s, SimConsole *con,
-            IntrControl *intctrl, PciConfigAll *pci,
-            int intrFreq);
+    Tsunami(const std::string &name, System *s, IntrControl *intctrl,
+            PciConfigAll *pci, int intrFreq);
+
+    virtual void postConsoleInt();
+    virtual void clearConsoleInt();
 
     virtual void serialize(std::ostream &os);
     virtual void unserialize(Checkpoint *cp, const std::string §ion);
 
             req->vaddr, req->size, req->vaddr & 0xfff);
 
     Addr daddr = (req->paddr - (addr & PA_IMPL_MASK));
-//    ExecContext *xc = req->xc;
-//    int cpuid = xc->cpu_id;
+
 
     switch(req->size) {
       case sizeof(uint8_t):
         switch(daddr) {
+          case TSDEV_PIC1_ISR:
+              // !!! If this is modified 64bit case needs to be too
+              // Pal code has to do a 64 bit physical read because there is
+              // no load physical byte instruction
+              *(uint8_t*)data = picr;
+              return No_Fault;
+          case TSDEV_PIC2_ISR:
+              // PIC2 not implemnted... just return 0
+              *(uint8_t*)data = 0x00;
+              return No_Fault;
           case TSDEV_TMR_CTL:
             *(uint8_t*)data = timer2.Status();
             return No_Fault;
         }
       case sizeof(uint16_t):
       case sizeof(uint32_t):
+        panic("I/O Read - invalid size - va %#x size %d\n",
+              req->vaddr, req->size);
+
       case sizeof(uint64_t):
+       switch(daddr) {
+          case TSDEV_PIC1_ISR:
+              // !!! If this is modified 8bit case needs to be too
+              // Pal code has to do a 64 bit physical read because there is
+              // no load physical byte instruction
+              *(uint64_t*)data = (uint64_t)picr;
+              return No_Fault;
+          default:
+              panic("I/O Read - invalid size - va %#x size %d\n",
+                    req->vaddr, req->size);
+       }
+
       default:
         panic("I/O Read - invalid size - va %#x size %d\n",
               req->vaddr, req->size);
       case sizeof(uint8_t):
         switch(daddr) {
           case TSDEV_PIC1_MASK:
-            mask1 = *(uint8_t*)data;
+            mask1 = ~(*(uint8_t*)data);
             if ((picr & mask1) && !picInterrupting) {
                 picInterrupting = true;
                 tsunami->cchip->postDRIR(55);
                 DPRINTF(Tsunami, "posting pic interrupt to cchip\n");
             }
+            if ((!(picr & mask1)) && picInterrupting) {
+                picInterrupting = false;
+                tsunami->cchip->clearDRIR(55);
+                DPRINTF(Tsunami, "clearing pic interrupt\n");
+            }
             return No_Fault;
           case TSDEV_PIC2_MASK:
             mask2 = *(uint8_t*)data;
             //PIC2 Not implemented to interrupt
             return No_Fault;
+          case TSDEV_PIC1_ACK:
+            // clear the interrupt on the PIC
+            picr &= ~(1 << (*(uint8_t*)data & 0xF));
+            if (!(picr & mask1))
+                tsunami->cchip->clearDRIR(55);
+            return No_Fault;
+          case TSDEV_PIC2_ACK:
+            return No_Fault;
           case TSDEV_DMA1_RESET:
             return No_Fault;
           case TSDEV_DMA2_RESET:
 {
     //PIC2 Is not implemented, because nothing of interest there
     picr |= bitvector;
-    if ((picr & mask1) && !picInterrupting) {
-        picInterrupting = true;
+    if (picr & mask1) {
         tsunami->cchip->postDRIR(55);
         DPRINTF(Tsunami, "posting pic interrupt to cchip\n");
     }
     //PIC2 Is not implemented, because nothing of interest there
     picr &= ~bitvector;
     if (!(picr & mask1)) {
-        picInterrupting = false;
         tsunami->cchip->clearDRIR(55);
         DPRINTF(Tsunami, "clearing pic interrupt to cchip\n");
     }
 
 #include "base/trace.hh"
 #include "dev/console.hh"
 #include "dev/tsunami_uart.hh"
+#include "mem/bus/bus.hh"
+#include "mem/bus/pio_interface.hh"
+#include "mem/bus/pio_interface_impl.hh"
 #include "mem/functional_mem/memory_control.hh"
 #include "sim/builder.hh"
 #include "targetarch/ev5.hh"
 #define CONS_INT_TX   0x01  // interrupt enable / state bits
 #define CONS_INT_RX   0x02
 
-TsunamiUart::TsunamiUart(const string &name, SimConsole *c, Addr a,
-                         MemoryController *mmu)
-    : FunctionalMemory(name), addr(a), cons(c), status_store(0),
-      valid_char(false)
+TsunamiUart::TsunamiUart(const string &name, SimConsole *c,
+                         MemoryController *mmu, Addr a,
+                         HierParams *hier, Bus *bus)
+    : PioDevice(name), addr(a), cons(c), status_store(0), valid_char(false)
 {
     mmu->add_child(this, Range<Addr>(addr, addr + size));
 
+    if (bus) {
+        pioInterface = newPioInterface(name, hier, bus, this,
+                                      &TsunamiUart::cacheAccess);
+         pioInterface->addAddrRange(addr, addr + size - 1);
+    }
+
     IER = 0;
 }
 
         break;
     }
 
-    switch (daddr) {
+
+    switch(daddr) {
       case 0x5: // Status Register
         {
             int status = cons->intStatus();
     Addr daddr = req->paddr - (addr & PA_IMPL_MASK);
 
     DPRINTF(TsunamiUart, " write register %#x value %#x\n", daddr, *(uint8_t*)data);
+
     switch (daddr) {
       case 0x3:
         status_store = *data;
         switch (*data) {
-          case 0x03: // going to read RR3
-            return No_Fault;
+                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");
+                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;
-            }
+                        cons->clearInt(CONS_INT_TX);
+                        return No_Fault;
+                }
 
-          case 0x00:
-          case 0x01:
-          case 0x12:
-            // going to write data???
-            return No_Fault;
+        case 0x00:
+        case 0x01:
+        case 0x12:
+        // going to write data???
+        return No_Fault;
 
-          default:
+        default:
             DPRINTF(TsunamiUart, "writing status register %#x \n",
                     *(uint8_t *)data);
             return No_Fault;
         }
 
       case 0x0: // Data register (TX)
-        cons->out(*(uint64_t *)data);
-        return No_Fault;
+        char ourchar;
+        ourchar = *(uint64_t *)data;
+        if ((isprint(ourchar) || iscntrl(ourchar)) && (ourchar != 0x0C))
+                cons->out(ourchar);
+        if (UART_IER_THRI & IER)
+            cons->setInt(CONS_INT_TX);
+            return No_Fault;
+        break;
       case 0x1: // DLM
         DPRINTF(TsunamiUart, "writing to DLM/IER %#x\n", *(uint8_t*)data);
         IER = *(uint8_t*)data;
+        if (UART_IER_THRI & IER)
+            cons->setInt(CONS_INT_TX);
         return No_Fault;
+        break;
       case 0x4: // MCR
         DPRINTF(TsunamiUart, "writing to MCR %#x\n", *(uint8_t*)data);
         return No_Fault;
     return No_Fault;
 }
 
+Tick
+TsunamiUart::cacheAccess(MemReqPtr &req)
+{
+    return curTick + 1000;
+}
+
 void
 TsunamiUart::serialize(ostream &os)
 {
     SimObjectParam<SimConsole *> console;
     SimObjectParam<MemoryController *> mmu;
     Param<Addr> addr;
+    SimObjectParam<Bus*> io_bus;
+    SimObjectParam<HierParams *> hier;
+
 
 END_DECLARE_SIM_OBJECT_PARAMS(TsunamiUart)
 
 
     INIT_PARAM(console, "The console"),
     INIT_PARAM(mmu, "Memory Controller"),
-    INIT_PARAM(addr, "Device Address")
+    INIT_PARAM(addr, "Device Address"),
+    INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL),
+    INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams)
 
 END_INIT_SIM_OBJECT_PARAMS(TsunamiUart)
 
 CREATE_SIM_OBJECT(TsunamiUart)
 {
-    return new TsunamiUart(getInstanceName(), console, addr, mmu);
+    return new TsunamiUart(getInstanceName(), console, mmu, addr, hier, io_bus);
 }
 
 REGISTER_SIM_OBJECT("TsunamiUart", TsunamiUart)
 
 #ifndef __TSUNAMI_UART_HH__
 #define __TSUNAMI_UART_HH__
 
-#include "mem/functional_mem/functional_memory.hh"
+#include "dev/tsunamireg.h"
+#include "base/range.hh"
+#include "dev/io_device.hh"
 
 class SimConsole;
 
 /*
  * Tsunami UART
  */
-class TsunamiUart : public FunctionalMemory
+class TsunamiUart : public PioDevice
 {
   private:
     Addr addr;
     uint8_t IER;
 
   public:
-    TsunamiUart(const std::string &name, SimConsole *c, Addr a,
-                MemoryController *mmu);
+    TsunamiUart(const string &name, SimConsole *c, MemoryController *mmu,
+            Addr a, HierParams *hier, Bus *bus);
 
     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);
+
+  public:
+    Tick cacheAccess(MemReqPtr &req);
 };
 
 #endif // __TSUNAMI_UART_HH__
 
 // I/O Ports
 #define TSDEV_PIC1_MASK     0x21
 #define TSDEV_PIC2_MASK     0xA1
+#define TSDEV_PIC1_ISR      0x20
+#define TSDEV_PIC2_ISR      0xA0
+#define TSDEV_PIC1_ACK      0x20
+#define TSDEV_PIC2_ACK      0xA0
 #define TSDEV_DMA1_RESET    0x0D
 #define TSDEV_DMA2_RESET    0xDA
 #define TSDEV_DMA1_MODE     0x0B
 #define RTC_CONTROL_REGISTERD   13     // control register D
 #define RTC_REGNUMBER_RTC_CR1   0x6A   // control register 1
 
-#define PCHIP_PCI0_MEMORY       0x10000000000ULL
-#define PCHIP_PCI0_IO           0x101FC000000ULL
+#define PCHIP_PCI0_MEMORY       ULL(0x10000000000)
+#define PCHIP_PCI0_IO           ULL(0x101FC000000)
 #define TSUNAMI_PCI0_MEMORY     ALPHA_K0SEG_BASE + PCHIP_PCI0_MEMORY
 #define TSUNAMI_PCI0_IO         ALPHA_K0SEG_BASE + PCHIP_PCI0_IO
 
 
+// UART Defines
+
+
+#define UART_IER_THRI           0x02
+#define UART_IER_RLSI           0x04
+
 #endif // __TSUNAMIREG_H__
 
     RemoteGDB *rgdb = new RemoteGDB(this, xc);
     GDBListener *gdbl = new GDBListener(rgdb, 7000 + xcIndex);
     gdbl->listen();
-    gdbl->accept();
+    //gdbl->accept();
 
     if (remoteGDB.size() <= xcIndex) {
         remoteGDB.resize(xcIndex+1);