self.bridge = Bridge()
     self.t1000 = T1000()
     self.t1000.attachIO(self.iobus)
-    self.physmem = PhysicalMemory(range = AddrRange(mdesc.mem()), zero = True)
+    self.physmem = PhysicalMemory(range = AddrRange('64MB'), zero = True)
+    self.physmem2 = PhysicalMemory(range = AddrRange(Addr('2GB'), size ='256MB'), zero = True)
     self.bridge.side_a = self.iobus.port
     self.bridge.side_b = self.membus.port
     self.physmem.port = self.membus.port
+    self.physmem2.port = self.membus.port
     self.rom.port = self.membus.port
     self.nvram.port = self.membus.port
     self.hypervisor_desc.port = self.membus.port
 
                 //1 should cause an illegal instruction exception
                 0x02: NoPriv::rdccr({{Rd = Ccr;}});
                 0x03: NoPriv::rdasi({{Rd = Asi;}});
-                0x04: PrivCheck::rdtick({{Rd = Tick;}}, {{Tick<63:>}});
+                0x04: PrivCheck::rdtick(
+                  {{ Rd = xc->readMiscRegWithEffect(MISCREG_TICK);}},
+                  {{Tick<63:>}});
                 0x05: NoPriv::rdpc({{
                     if(Pstate<3:>)
                         Rd = (xc->readPC())<31:0>;
                 }});
                 //0x14-0x15 should cause an illegal instruction exception
                 0x16: Priv::rdsoftint({{Rd = Softint;}});
-                0x17: Priv::rdtick_cmpr({{Rd = TickCmpr;}});
-                0x18: PrivCheck::rdstick({{Rd = Stick}}, {{Stick<63:>}});
-                0x19: Priv::rdstick_cmpr({{Rd = StickCmpr;}});
+                0x17: Priv::rdtick_cmpr({{
+                    Rd = xc->readMiscRegWithEffect(MISCREG_TICK_CMPR);
+                }});
+                0x18: PrivCheck::rdstick({{
+                   Rd = xc->readMiscRegWithEffect(MISCREG_STICK);
+                }}, {{Stick<63:>}});
+                0x19: Priv::rdstick_cmpr({{
+                    Rd = xc->readMiscRegWithEffect(MISCREG_STICK_CMPR);
+                }});
                 0x1A: Priv::rdstrand_sts_reg({{
                     if(Pstate<2:> && !Hpstate<2:>)
                         Rd = StrandStsReg<0:>;
                 0x05: HPriv::rdhprhtba({{Rd = Htba;}});
                 0x06: HPriv::rdhprhver({{Rd = Hver;}});
                 //0x07-0x1E should cause an illegal instruction exception
-                0x1F: HPriv::rdhprhstick_cmpr({{Rd = HstickCmpr;}});
+                0x1F: HPriv::rdhprhstick_cmpr({{
+                    Rd = xc->readMiscRegWithEffect(MISCREG_HSTICK_CMPR);
+                }});
             }
             0x2A: decode RS1 {
                 0x00: Priv::rdprtpc({{
                         return new IllegalInstruction;
                     Rd = Tt;
                 }});
-                0x04: Priv::rdprtick({{Rd = Tick;}});
+                0x04: Priv::rdprtick({{
+                    Rd = xc->readMiscRegWithEffect(MISCREG_TICK);
+                }});
                 0x05: Priv::rdprtba({{Rd = Tba;}});
                 0x06: Priv::rdprpstate({{Rd = Pstate;}});
                 0x07: Priv::rdprtl({{Rd = Tl;}});
                 0x14: Priv::wrsoftint_set({{SoftintSet = Rs1 ^ Rs2_or_imm13;}});
                 0x15: Priv::wrsoftint_clr({{SoftintClr = Rs1 ^ Rs2_or_imm13;}});
                 0x16: Priv::wrsoftint({{Softint = Rs1 ^ Rs2_or_imm13;}});
-                0x17: Priv::wrtick_cmpr({{TickCmpr = Rs1 ^ Rs2_or_imm13;}});
+                0x17: Priv::wrtick_cmpr({{
+                      xc->setMiscRegWithEffect(MISCREG_TICK_CMPR, Rs1 ^ Rs2_or_imm13);
+                }});
                 0x18: NoPriv::wrstick({{
                     if(!Hpstate<2:>)
                         return new IllegalInstruction;
-                    Stick = Rs1 ^ Rs2_or_imm13;
+                    xc->setMiscRegWithEffect(MISCREG_STICK, Rs1 ^ Rs2_or_imm13);
+                }});
+                0x19: Priv::wrstick_cmpr({{
+                    xc->setMiscRegWithEffect(MISCREG_STICK_CMPR, Rs1 ^ Rs2_or_imm13);
                 }});
-                0x19: Priv::wrstick_cmpr({{StickCmpr = Rs1 ^ Rs2_or_imm13;}});
                 0x1A: Priv::wrstrand_sts_reg({{
                     if(Pstate<2:> && !Hpstate<2:>)
                         StrandStsReg = StrandStsReg<63:1> |
                     else
                         Tt = Rs1 ^ Rs2_or_imm13;
                 }});
-                0x04: HPriv::wrprtick({{Tick = Rs1 ^ Rs2_or_imm13;}});
+                0x04: HPriv::wrprtick({{
+                    xc->setMiscRegWithEffect(MISCREG_TICK, Rs1 ^ Rs2_or_imm13);
+                }});
                 0x05: Priv::wrprtba({{Tba = Rs1 ^ Rs2_or_imm13;}});
                 0x06: Priv::wrprpstate({{Pstate = Rs1 ^ Rs2_or_imm13;}});
                 0x07: Priv::wrprtl({{
                 //0x04 should cause an illegal instruction exception
                 0x05: HPriv::wrhprhtba({{Htba = Rs1 ^ Rs2_or_imm13;}});
                 //0x06-0x01D should cause an illegal instruction exception
-                0x1F: HPriv::wrhprhstick_cmpr({{HstickCmpr = Rs1 ^ Rs2_or_imm13;}});
+                0x1F: HPriv::wrhprhstick_cmpr({{
+                    xc->setMiscRegWithEffect(MISCREG_HSTICK_CMPR, Rs1 ^ Rs2_or_imm13);
+                }});
             }
             0x34: decode OPF{
                 format BasicOperate{
 
     y = 0;
     ccr = 0;
     asi = 0;
-    tick = 0;
+    tick = ULL(1) << 63;
     fprs = 0;
     gsr = 0;
     softint = 0;
 MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc)
 {
     switch (miscReg) {
+        // tick and stick are aliased to each other in niagra
+        case MISCREG_STICK:
         case MISCREG_TICK:
         case MISCREG_PRIVTICK:
-          return tc->getCpuPtr()->curCycle() - (tick & mask(63)) |
-              (tick & ~(mask(63))) << 63;
+          // I'm not sure why legion ignores the lowest two bits, but we'll go
+          // with it
+          // change from curCycle() to instCount() until we're done with legion
+          DPRINTFN("Instruction Count when STICK read: %#X\n",
+                  tc->getCpuPtr()->instCount());
+          uint64_t t1 =  mbits(tc->getCpuPtr()->instCount() - (tick &
+                      mask(63)),62,2);
+          uint64_t t2 = mbits(tick,63,63) ;
+          return t1 | t2;
         case MISCREG_FPRS:
           panic("FPU not implemented\n");
         case MISCREG_PCR:
           panic("Floating Point not implemented\n");
 //We'll include this only in FS so we don't need the SparcSystem type around
 //in SE.
-#if FULL_SYSTEM
+/*#if FULL_SYSTEM
         case MISCREG_STICK:
           SparcSystem *sys;
           sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
           assert(sys != NULL);
           return curTick/Clock::Int::ns - sys->sysTick | (stick & ~(mask(63)));
-#endif
+#endif*/
         case MISCREG_HVER:
           return NWindows | MaxTL << 8 | MaxGL << 16;
     }
     SparcSystem *sys;
 #endif
     switch (miscReg) {
+        case MISCREG_STICK:
         case MISCREG_TICK:
-          tick = tc->getCpuPtr()->curCycle() - val  & ~Bit64;
+          // change from curCycle() to instCount() until we're done with legion
+          tick = tc->getCpuPtr()->instCount() - val  & ~Bit64;
           tick |= val & Bit64;
           break;
         case MISCREG_FPRS:
 //We'll include this only in FS so we don't need the SparcSystem type around
 //in SE.
 #if FULL_SYSTEM
-        case MISCREG_STICK:
+        // @todo figure out how we're actualy going to do this. In niagra the
+        // registers are aliased to the same thing (see tick above)
+        /*case MISCREG_STICK:
           sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
           assert(sys != NULL);
           sys->sysTick = curTick/Clock::Int::ns - val & ~Bit64;
           stick |= val & Bit64;
-          break;
+          break;*/
         case MISCREG_STICK_CMPR:
           if (sTickCompare == NULL)
               sTickCompare = new STickCompareEvent(this, tc);
 
     return (val >> last) & mask(nbits);
 }
 
+/**
+ * Mask off the given bits in place like bits() but without shifting.
+ * msb = 63, lsb = 0
+ */
+template <class T>
+inline
+T
+mbits(T val, int first, int last)
+{
+    return val & (mask(first+1) & ~mask(last));
+}
+
 /**
  * Sign-extend an N-bit value to 64 bits.
  */
 
 
 #if FULL_SYSTEM
 BaseCPU::BaseCPU(Params *p)
-    : MemObject(p->name), clock(p->clock), checkInterrupts(true),
+    : MemObject(p->name), clock(p->clock), instCnt(0), checkInterrupts(true),
       params(p), number_of_threads(p->numberOfThreads), system(p->system),
       phase(p->phase)
 #else
 
   protected:
     // CPU's clock period in terms of the number of ticks of curTime.
     Tick clock;
+    // @todo remove me after debugging with legion done
+    Tick instCnt;
 
   public:
 //    Tick currentTick;
     inline Tick frequency() const { return Clock::Frequency / clock; }
     inline Tick cycles(int numCycles) const { return clock * numCycles; }
     inline Tick curCycle() const { return curTick / clock; }
+    // @todo remove me after debugging with legion done
+    Tick instCount() { return instCnt; }
 
     /** The next cycle the CPU should be scheduled, given a cache
      * access or quiesce event returning on this cycle.  This function
 
     {
         bool compared = false;
         bool diffPC   = false;
+        bool diffCC   = false;
         bool diffInst = false;
         bool diffRegs = false;
         bool diffTpc = false;
                     lgnPc = shared_data->pc & TheISA::PAddrImplMask;
                     if (lgnPc != m5Pc)
                        diffPC = true;
+
+                    if (shared_data->cycle_count !=
+                            thread->getCpuPtr()->instCount())
+                        diffCC = true;
+
                     if (shared_data->instruction !=
                             (SparcISA::MachInst)staticInst->machInst) {
                         diffInst = true;
                     if(shared_data->cleanwin != thread->readMiscReg(MISCREG_CLEANWIN))
                         diffCleanwin = true;
 
-                    if (diffPC || diffInst || diffRegs || diffTpc || diffTnpc ||
-                            diffTstate || diffTt || diffHpstate ||
+                    if (diffPC || diffCC || diffInst || diffRegs || diffTpc ||
+                            diffTnpc || diffTstate || diffTt || diffHpstate ||
                             diffHtstate || diffHtba || diffPstate || diffY ||
                             diffCcr || diffTl || diffGl || diffAsi || diffPil ||
                             diffCwp || diffCansave || diffCanrestore ||
                         outs << "Differences found between M5 and Legion:";
                         if (diffPC)
                             outs << " [PC]";
+                        if (diffCC)
+                            outs << " [CC]";
                         if (diffInst)
                             outs << " [Instruction]";
                         if (diffRegs)
                              << "Legion PC: " << "0x"<< setw(16) << setfill('0') << hex
                              << lgnPc << endl << endl;
 
+                        outs << right << setfill(' ') << setw(15)
+                             << "M5 CC: " << "0x"<< setw(16) << setfill('0')
+                             << hex << thread->getCpuPtr()->instCount() << endl;
+                        outs << setfill(' ') << setw(15)
+                             << "Legion CC: " << "0x"<< setw(16) << setfill('0') << hex
+                             << shared_data->cycle_count << endl << endl;
+
                         outs << setfill(' ') << setw(15)
                              << "M5 Inst: "  << "0x"<< setw(8)
                              << setfill('0') << hex << staticInst->machInst
 
 
 #include <unistd.h>
 
-#define VERSION         0xA1000005
+#define VERSION         0xA1000006
 #define OWN_M5          0x000000AA
 #define OWN_LEGION      0x00000055
 
 
     uint64_t pc;
     uint64_t new_pc;
+    uint64_t cycle_count;
+    uint64_t new_cycle_count;
     uint32_t instruction;
     uint32_t new_instruction;
     uint64_t intregs[32];
 
         else
             dcache_latency = dcachePort.sendAtomic(pkt);
         dcache_access = true;
-
-        assert(pkt->result == Packet::Success);
+#if !defined(NDEBUG)
+        if (pkt->result != Packet::Success)
+            panic("Unable to find responder for address pa = %#X va = %#X\n",
+                    pkt->req->getPaddr(), pkt->req->getVaddr());
+#endif
         data = pkt->get<T>();
 
         if (req->isLocked()) {
             }
             dcache_access = true;
 
-            assert(pkt->result == Packet::Success);
+#if !defined(NDEBUG)
+            if (pkt->result != Packet::Success)
+                panic("Unable to find responder for address pa = %#X va = %#X\n",
+                        pkt->req->getPaddr(), pkt->req->getVaddr());
+#endif
         }
 
         if (req->isLocked()) {
 
             dcache_access = false; // assume no dcache access
             preExecute();
+
             fault = curStaticInst->execute(this, traceData);
             postExecute();
 
+            // @todo remove me after debugging with legion done
+            if (curStaticInst && (!curStaticInst->isMicroOp() ||
+                        curStaticInst->isLastMicroOp()))
+                instCnt++;
+
             if (simulate_stalls) {
                 Tick icache_stall = icache_latency - cycles(1);
                 Tick dcache_stall =
 
     if (!params()->retBadAddr)
         pioSize = p->pio_size;
 
-    memset(&retData, p->retData, sizeof(retData));
+    retData8 = params()->retData8;
+    retData16 = params()->retData16;
+    retData32 = params()->retData32;
+    retData64 = params()->retData64;
 }
 
 Tick
 {
     assert(pkt->result == Packet::Unknown);
 
+    if (params()->warnAccess != "")
+        warn("Device %s accessed by read to address %#x size=%d\n",
+                name(), pkt->getAddr(), pkt->getSize());
     if (params()->retBadAddr) {
         DPRINTF(Tsunami, "read to bad address va=%#x size=%d\n",
                 pkt->getAddr(), pkt->getSize());
                 pkt->getAddr(), pkt->getSize());
         switch (pkt->getSize()) {
           case sizeof(uint64_t):
-             pkt->set(retData);
+             pkt->set(retData64);
              break;
           case sizeof(uint32_t):
-             pkt->set((uint32_t)retData);
+             pkt->set(retData32);
              break;
           case sizeof(uint16_t):
-             pkt->set((uint16_t)retData);
+             pkt->set(retData16);
              break;
           case sizeof(uint8_t):
-             pkt->set((uint8_t)retData);
+             pkt->set(retData8);
              break;
           default:
             panic("invalid access size!\n");
 Tick
 IsaFake::write(PacketPtr pkt)
 {
+    if (params()->warnAccess != "") {
+        uint64_t data;
+        switch (pkt->getSize()) {
+          case sizeof(uint64_t):
+            data = pkt->get<uint64_t>();
+            break;
+          case sizeof(uint32_t):
+            data = pkt->get<uint32_t>();
+            break;
+          case sizeof(uint16_t):
+            data = pkt->get<uint16_t>();
+            break;
+          case sizeof(uint8_t):
+            data = pkt->get<uint8_t>();
+            break;
+          default:
+            panic("invalid access size!\n");
+        }
+        warn("Device %s accessed by write to address %#x size=%d data=%#x\n",
+                name(), pkt->getAddr(), pkt->getSize(), data);
+    }
     if (params()->retBadAddr) {
         DPRINTF(Tsunami, "write to bad address va=%#x size=%d \n",
                 pkt->getAddr(), pkt->getSize());
     } else {
         DPRINTF(Tsunami, "write - va=%#x size=%d \n",
                 pkt->getAddr(), pkt->getSize());
+
+        if (params()->updateData) {
+            switch (pkt->getSize()) {
+              case sizeof(uint64_t):
+                retData64 = pkt->get<uint64_t>();
+                break;
+              case sizeof(uint32_t):
+                retData32 = pkt->get<uint32_t>();
+                break;
+              case sizeof(uint16_t):
+                retData16 = pkt->get<uint16_t>();
+                break;
+              case sizeof(uint8_t):
+                retData8 = pkt->get<uint8_t>();
+                break;
+              default:
+                panic("invalid access size!\n");
+            }
+        }
         pkt->result = Packet::Success;
     }
     return pioDelay;
     Param<Tick> pio_latency;
     Param<Addr> pio_size;
     Param<bool> ret_bad_addr;
-    Param<uint8_t> ret_data;
+    Param<bool> update_data;
+    Param<std::string> warn_access;
+    Param<uint8_t> ret_data8;
+    Param<uint16_t> ret_data16;
+    Param<uint32_t> ret_data32;
+    Param<uint64_t> ret_data64;
     SimObjectParam<Platform *> platform;
     SimObjectParam<System *> system;
 
     INIT_PARAM(pio_latency, "Programmed IO latency"),
     INIT_PARAM(pio_size, "Size of address range"),
     INIT_PARAM(ret_bad_addr, "Return pkt status BadAddr"),
-    INIT_PARAM(ret_data, "Data to return if not bad addr"),
+    INIT_PARAM(update_data, "Update returned data"),
+    INIT_PARAM(warn_access, "Warn if this device is touched"),
+    INIT_PARAM(ret_data8, "Data to return if not bad addr"),
+    INIT_PARAM(ret_data16, "Data to return if not bad addr"),
+    INIT_PARAM(ret_data32, "Data to return if not bad addr"),
+    INIT_PARAM(ret_data64, "Data to return if not bad addr"),
     INIT_PARAM(platform, "platform"),
     INIT_PARAM(system, "system object")
 
     p->pio_delay = pio_latency;
     p->pio_size = pio_size;
     p->retBadAddr = ret_bad_addr;
-    p->retData = ret_data;
+    p->updateData = update_data;
+    p->warnAccess = warn_access;
+    p->retData8= ret_data8;
+    p->retData16 = ret_data16;
+    p->retData32 = ret_data32;
+    p->retData64 = ret_data64;
     p->platform = platform;
     p->system = system;
     return new IsaFake(p);
 
 #include "dev/alpha/tsunami.hh"
 #include "mem/packet.hh"
 
+#include <string>
+
 /**
  * IsaFake is a device that returns, BadAddr, 1 or 0 on all reads and
  *  rites. It is meant to be placed at an address range
     {
         Addr pio_size;
         bool retBadAddr;
-        uint8_t retData;
+        bool updateData;
+        uint8_t retData8;
+        uint16_t retData16;
+        uint32_t retData32;
+        uint64_t retData64;
+        std::string warnAccess;
     };
   protected:
     const Params *params() const { return (const Params*)_params; }
-    uint64_t retData;
+    uint8_t retData8;
+    uint16_t retData16;
+    uint32_t retData32;
+    uint64_t retData64;
+
 
   public:
     /**
 
 class IsaFake(BasicPioDevice):
     type = 'IsaFake'
     pio_size = Param.Addr(0x8, "Size of address range")
-    ret_data = Param.UInt8(0xFF, "Default data to return")
+    ret_data8 = Param.UInt8(0xFF, "Default data to return")
+    ret_data16 = Param.UInt16(0xFFFF, "Default data to return")
+    ret_data32 = Param.UInt32(0xFFFFFFFF, "Default data to return")
+    ret_data64 = Param.UInt64(0xFFFFFFFFFFFFFFFF, "Default data to return")
     ret_bad_addr = Param.Bool(False, "Return pkt status bad address on access")
+    update_data = Param.Bool(False, "Update the data that is returned on writes")
+    warn_access = Param.String("", "String to print when device is accessed")
 
 class BadAddr(IsaFake):
     ret_bad_addr = Param.Bool(True, "Return pkt status bad address on access")
 
     type = 'T1000'
     system = Param.System(Parent.any, "system")
 
-    fake_iob = IsaFake(pio_addr=0x8000000000, pio_size=0x7F00000000)
+    fake_clk = IsaFake(pio_addr=0x9600000000, pio_size=0x100000000,
+            warn_access="Accessing Clock Unit -- Unimplemented!")
 
-    uart = Uart8250(pio_addr=0xfff0c2c000)
+    fake_membnks = IsaFake(pio_addr=0x9700000000, pio_size=16384,
+            ret_data64=0x0000000000000000, update_data=False,
+            warn_access="Accessing Memory Banks -- Unimplemented!")
+
+    fake_iob = IsaFake(pio_addr=0x9800000000, pio_size=0x100000000,
+            warn_access="Accessing IOB -- Unimplemented!")
+
+    fake_jbi = IsaFake(pio_addr=0x8000000000, pio_size=0x100000000,
+            warn_access="Accessing JBI -- Unimplemented!")
+
+    fake_l2_1 = IsaFake(pio_addr=0xA900000000, pio_size=0x8,
+            ret_data64=0x0000000000000001, update_data=True,
+            warn_access="Accessing L2 Cache Banks -- Unimplemented!")
+
+    fake_l2_2 = IsaFake(pio_addr=0xA900000040, pio_size=0x8,
+            ret_data64=0x0000000000000001, update_data=True,
+            warn_access="Accessing L2 Cache Banks -- Unimplemented!")
+
+    fake_l2_3 = IsaFake(pio_addr=0xA900000080, pio_size=0x8,
+            ret_data64=0x0000000000000001, update_data=True,
+            warn_access="Accessing L2 Cache Banks -- Unimplemented!")
+
+    fake_l2_4 = IsaFake(pio_addr=0xA9000000C0, pio_size=0x8,
+            ret_data64=0x0000000000000001, update_data=True,
+            warn_access="Accessing L2 Cache Banks -- Unimplemented!")
+
+    fake_ssi = IsaFake(pio_addr=0xff00000000, pio_size=0x10000000,
+            warn_access="Accessing SSI -- Unimplemented!")
+
+    hvuart = Uart8250(pio_addr=0xfff0c2c000)
+    puart0 = Uart8250(pio_addr=0x1f10000000)
     console = SimConsole(listener = ConsoleListener())
 
     # Attach I/O devices to specified bus object.  Can't do this
     # earlier, since the bus object itself is typically defined at the
     # System level.
     def attachIO(self, bus):
+        self.fake_clk.pio = bus.port
+        self.fake_membnks.pio = bus.port
         self.fake_iob.pio = bus.port
-        self.uart.pio = bus.port
+        self.fake_jbi.pio = bus.port
+        self.fake_l2_1.pio = bus.port
+        self.fake_l2_2.pio = bus.port
+        self.fake_l2_3.pio = bus.port
+        self.fake_l2_4.pio = bus.port
+        self.fake_ssi.pio = bus.port
+        self.puart0.pio = bus.port
+        self.hvuart.pio = bus.port