ISA: Set up common trace flags for tracing registers.
[gem5.git] / src / arch / sparc / miscregfile.cc
index 7b0939c290d71397d84d1a8f4d5dd4654385d647..e06d4b15a5b6ae5bfa2fe0d6d1fb01990e23c55c 100644 (file)
 #include "cpu/base.hh"
 #include "cpu/thread_context.hh"
 
-#if FULL_SYSTEM
-#include "arch/sparc/system.hh"
-#endif
-
 using namespace SparcISA;
 using namespace std;
 
@@ -50,15 +46,20 @@ class Checkpoint;
 string SparcISA::getMiscRegName(RegIndex index)
 {
     static::string miscRegName[NumMiscRegs] =
-        {"y", "ccr", "asi", "tick", "fprs", "pcr", "pic",
+        {/*"y", "ccr",*/ "asi", "tick", "fprs", "pcr", "pic",
          "gsr", "softint_set", "softint_clr", "softint", "tick_cmpr",
          "stick", "stick_cmpr",
          "tpc", "tnpc", "tstate", "tt", "privtick", "tba", "pstate", "tl",
-         "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
-         "wstate", "gl",
+         "pil", "cwp", /*"cansave", "canrestore", "cleanwin", "otherwin",
+         "wstate",*/ "gl",
          "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg",
          "hstick_cmpr",
-         "fsr"};
+         "fsr", "prictx", "secctx", "partId", "lsuCtrlReg",
+         "scratch0", "scratch1", "scratch2", "scratch3", "scratch4",
+         "scratch5", "scratch6", "scratch7", "cpuMondoHead", "cpuMondoTail",
+         "devMondoHead", "devMondoTail", "resErrorHead", "resErrorTail",
+         "nresErrorHead", "nresErrorTail", "TlbData" };
+
     return miscRegName[index];
 }
 
@@ -69,10 +70,10 @@ enum RegMask
 
 void MiscRegFile::clear()
 {
-    y = 0;
-    ccr = 0;
+    //y = 0;
+    //ccr = 0;
     asi = 0;
-    tick = 0;
+    tick = ULL(1) << 63;
     fprs = 0;
     gsr = 0;
     softint = 0;
@@ -87,11 +88,11 @@ void MiscRegFile::clear()
     tl = 0;
     pil = 0;
     cwp = 0;
-    cansave = 0;
-    canrestore = 0;
-    cleanwin = 0;
-    otherwin = 0;
-    wstate = 0;
+    //cansave = 0;
+    //canrestore = 0;
+    //cleanwin = 0;
+    //otherwin = 0;
+    //wstate = 0;
     gl = 0;
     //In a T1, bit 11 is apparently always 1
     hpstate = (1 << 11);
@@ -102,448 +103,644 @@ void MiscRegFile::clear()
     //This is set this way in Legion for some reason
     strandStatusReg = 0x50000;
     fsr = 0;
-    implicitInstAsi = ASI_PRIMARY;
-    implicitDataAsi = ASI_PRIMARY;
+
+    priContext = 0;
+    secContext = 0;
+    partId = 0;
+    lsuCtrlReg = 0;
+
+    memset(scratchPad, 0, sizeof(scratchPad));
+#if FULL_SYSTEM
+    tickCompare = NULL;
+    sTickCompare = NULL;
+    hSTickCompare = NULL;
+#endif
 }
 
-MiscReg MiscRegFile::readReg(int miscReg)
+MiscReg MiscRegFile::readRegNoEffect(int miscReg)
 {
+
+  // The three miscRegs are moved up from the switch statement
+  // due to more frequent calls.
+
+  if (miscReg == MISCREG_GL)
+    return gl;
+  if (miscReg == MISCREG_CWP)
+    return cwp;
+  if (miscReg == MISCREG_TLB_DATA) {
+    /* Package up all the data for the tlb:
+     * 6666555555555544444444443333333333222222222211111111110000000000
+     * 3210987654321098765432109876543210987654321098765432109876543210
+     *   secContext   | priContext    |             |tl|partid|  |||||^hpriv
+     *                                                           ||||^red
+     *                                                           |||^priv
+     *                                                           ||^am
+     *                                                           |^lsuim
+     *                                                           ^lsudm
+     */
+    return bits((uint64_t)hpstate,2,2) |
+           bits((uint64_t)hpstate,5,5) << 1 |
+           bits((uint64_t)pstate,3,2) << 2 |
+           bits((uint64_t)lsuCtrlReg,3,2) << 4 |
+           bits((uint64_t)partId,7,0) << 8 |
+           bits((uint64_t)tl,2,0) << 16 |
+                (uint64_t)priContext << 32 |
+                (uint64_t)secContext << 48;
+  }
+
     switch (miscReg) {
-        case MISCREG_Y:
-          return y;
-        case MISCREG_CCR:
-          return ccr;
-        case MISCREG_ASI:
-          return asi;
-        case MISCREG_FPRS:
-          return fprs;
-        case MISCREG_TICK:
-           return tick;
-        case MISCREG_PCR:
-          panic("PCR not implemented\n");
-        case MISCREG_PIC:
-          panic("PIC not implemented\n");
-        case MISCREG_GSR:
-          return gsr;
-        case MISCREG_SOFTINT:
-           return softint;
-        case MISCREG_TICK_CMPR:
-           return tick_cmpr;
-        case MISCREG_STICK:
-           return stick;
-        case MISCREG_STICK_CMPR:
-           return stick_cmpr;
+      //case MISCREG_TLB_DATA:
+      //  [original contents see above]
+      //case MISCREG_Y:
+      //  return y;
+      //case MISCREG_CCR:
+      //  return ccr;
+      case MISCREG_ASI:
+        return asi;
+      case MISCREG_FPRS:
+        return fprs;
+      case MISCREG_TICK:
+        return tick;
+      case MISCREG_PCR:
+        panic("PCR not implemented\n");
+      case MISCREG_PIC:
+        panic("PIC not implemented\n");
+      case MISCREG_GSR:
+        return gsr;
+      case MISCREG_SOFTINT:
+        return softint;
+      case MISCREG_TICK_CMPR:
+        return tick_cmpr;
+      case MISCREG_STICK:
+        return stick;
+      case MISCREG_STICK_CMPR:
+        return stick_cmpr;
 
         /** Privilged Registers */
-        case MISCREG_TPC:
-          return tpc[tl-1];
-        case MISCREG_TNPC:
-          return tnpc[tl-1];
-        case MISCREG_TSTATE:
-          return tstate[tl-1];
-        case MISCREG_TT:
-          return tt[tl-1];
-        case MISCREG_PRIVTICK:
-          panic("Priviliged access to tick registers not implemented\n");
-        case MISCREG_TBA:
-          return tba;
-        case MISCREG_PSTATE:
-          return pstate;
-        case MISCREG_TL:
-          return tl;
-        case MISCREG_PIL:
-          return pil;
-        case MISCREG_CWP:
-          return cwp;
-        case MISCREG_CANSAVE:
-          return cansave;
-        case MISCREG_CANRESTORE:
-          return canrestore;
-        case MISCREG_CLEANWIN:
-          return cleanwin;
-        case MISCREG_OTHERWIN:
-          return otherwin;
-        case MISCREG_WSTATE:
-          return wstate;
-        case MISCREG_GL:
-          return gl;
+      case MISCREG_TPC:
+        return tpc[tl-1];
+      case MISCREG_TNPC:
+        return tnpc[tl-1];
+      case MISCREG_TSTATE:
+        return tstate[tl-1];
+      case MISCREG_TT:
+        return tt[tl-1];
+      case MISCREG_PRIVTICK:
+        panic("Priviliged access to tick registers not implemented\n");
+      case MISCREG_TBA:
+        return tba;
+      case MISCREG_PSTATE:
+        return pstate;
+      case MISCREG_TL:
+        return tl;
+      case MISCREG_PIL:
+        return pil;
+      //CWP, GL moved
+      //case MISCREG_CWP:
+      //  return cwp;
+      //case MISCREG_CANSAVE:
+      //  return cansave;
+      //case MISCREG_CANRESTORE:
+      //  return canrestore;
+      //case MISCREG_CLEANWIN:
+      //  return cleanwin;
+      //case MISCREG_OTHERWIN:
+      //  return otherwin;
+      //case MISCREG_WSTATE:
+      //  return wstate;
+      //case MISCREG_GL:
+      //  return gl;
 
         /** Hyper privileged registers */
-        case MISCREG_HPSTATE:
-          return hpstate;
-        case MISCREG_HTSTATE:
-          return htstate[tl-1];
-        case MISCREG_HINTP:
-          panic("HINTP not implemented\n");
-        case MISCREG_HTBA:
-          return htba;
-        case MISCREG_HVER:
-          return NWindows | MaxTL << 8 | MaxGL << 16;
-        case MISCREG_STRAND_STS_REG:
-          return strandStatusReg;
-        case MISCREG_HSTICK_CMPR:
-          return hstick_cmpr;
+      case MISCREG_HPSTATE:
+        return hpstate;
+      case MISCREG_HTSTATE:
+        return htstate[tl-1];
+      case MISCREG_HINTP:
+        return hintp;
+      case MISCREG_HTBA:
+        return htba;
+      case MISCREG_STRAND_STS_REG:
+        return strandStatusReg;
+      case MISCREG_HSTICK_CMPR:
+        return hstick_cmpr;
 
         /** Floating Point Status Register */
-        case MISCREG_FSR:
-          return fsr;
-        default:
-          panic("Miscellaneous register %d not implemented\n", miscReg);
+      case MISCREG_FSR:
+        DPRINTF(MiscRegs, "FSR read as: %#x\n", fsr);
+        return fsr;
+
+      case MISCREG_MMU_P_CONTEXT:
+        return priContext;
+      case MISCREG_MMU_S_CONTEXT:
+        return secContext;
+      case MISCREG_MMU_PART_ID:
+        return partId;
+      case MISCREG_MMU_LSU_CTRL:
+        return lsuCtrlReg;
+
+      case MISCREG_SCRATCHPAD_R0:
+        return scratchPad[0];
+      case MISCREG_SCRATCHPAD_R1:
+        return scratchPad[1];
+      case MISCREG_SCRATCHPAD_R2:
+        return scratchPad[2];
+      case MISCREG_SCRATCHPAD_R3:
+        return scratchPad[3];
+      case MISCREG_SCRATCHPAD_R4:
+        return scratchPad[4];
+      case MISCREG_SCRATCHPAD_R5:
+        return scratchPad[5];
+      case MISCREG_SCRATCHPAD_R6:
+        return scratchPad[6];
+      case MISCREG_SCRATCHPAD_R7:
+        return scratchPad[7];
+      case MISCREG_QUEUE_CPU_MONDO_HEAD:
+        return cpu_mondo_head;
+      case MISCREG_QUEUE_CPU_MONDO_TAIL:
+        return cpu_mondo_tail;
+      case MISCREG_QUEUE_DEV_MONDO_HEAD:
+        return dev_mondo_head;
+      case MISCREG_QUEUE_DEV_MONDO_TAIL:
+        return dev_mondo_tail;
+      case MISCREG_QUEUE_RES_ERROR_HEAD:
+        return res_error_head;
+      case MISCREG_QUEUE_RES_ERROR_TAIL:
+        return res_error_tail;
+      case MISCREG_QUEUE_NRES_ERROR_HEAD:
+        return nres_error_head;
+      case MISCREG_QUEUE_NRES_ERROR_TAIL:
+        return nres_error_tail;
+      default:
+        panic("Miscellaneous register %d not implemented\n", miscReg);
     }
 }
 
-MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc)
+MiscReg MiscRegFile::readReg(int miscReg, ThreadContext * tc)
 {
     switch (miscReg) {
-        case MISCREG_TICK:
-        case MISCREG_PRIVTICK:
-          return tc->getCpuPtr()->curCycle() - (tick & mask(63)) |
-              (tick & ~(mask(63))) << 63;
-        case MISCREG_FPRS:
-          panic("FPU not implemented\n");
-        case MISCREG_PCR:
-        case MISCREG_PIC:
-          panic("Performance Instrumentation not impl\n");
-        /** Floating Point Status Register */
-        case MISCREG_FSR:
-          panic("Floating Point not implemented\n");
-//We'll include this only in FS so we don't need the SparcSystem type around
-//in SE.
+        // tick and stick are aliased to each other in niagra
+        // well store the tick data in stick and the interrupt bit in tick
+      case MISCREG_STICK:
+      case MISCREG_TICK:
+      case MISCREG_PRIVTICK:
+        // 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
+        DPRINTF(Timer, "Instruction Count when TICK read: %#X stick=%#X\n",
+                tc->getCpuPtr()->instCount(), stick);
+        return mbits(tc->getCpuPtr()->instCount() + (int64_t)stick,62,2) |
+               mbits(tick,63,63);
+      case MISCREG_FPRS:
+        // in legion if fp is enabled du and dl are set
+        return fprs | 0x3;
+      case MISCREG_PCR:
+      case MISCREG_PIC:
+        panic("Performance Instrumentation not impl\n");
+      case MISCREG_SOFTINT_CLR:
+      case MISCREG_SOFTINT_SET:
+        panic("Can read from softint clr/set\n");
+      case MISCREG_SOFTINT:
+      case MISCREG_TICK_CMPR:
+      case MISCREG_STICK_CMPR:
+      case MISCREG_HINTP:
+      case MISCREG_HTSTATE:
+      case MISCREG_HTBA:
+      case MISCREG_HVER:
+      case MISCREG_STRAND_STS_REG:
+      case MISCREG_HSTICK_CMPR:
+      case MISCREG_QUEUE_CPU_MONDO_HEAD:
+      case MISCREG_QUEUE_CPU_MONDO_TAIL:
+      case MISCREG_QUEUE_DEV_MONDO_HEAD:
+      case MISCREG_QUEUE_DEV_MONDO_TAIL:
+      case MISCREG_QUEUE_RES_ERROR_HEAD:
+      case MISCREG_QUEUE_RES_ERROR_TAIL:
+      case MISCREG_QUEUE_NRES_ERROR_HEAD:
+      case MISCREG_QUEUE_NRES_ERROR_TAIL:
 #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)));
+      case MISCREG_HPSTATE:
+        return readFSReg(miscReg, tc);
+#else
+      case MISCREG_HPSTATE:
+        //HPSTATE is special because because sometimes in privilege
+        //checks for instructions it will read HPSTATE to make sure
+        //the priv. level is ok So, we'll just have to tell it it
+        //isn't, instead of panicing.
+        return 0;
+
+      panic("Accessing Fullsystem register %s in SE mode\n",
+            getMiscRegName(miscReg));
 #endif
-        case MISCREG_HVER:
-          return NWindows | MaxTL << 8 | MaxGL << 16;
+
     }
-    return readReg(miscReg);
+    return readRegNoEffect(miscReg);
 }
 
-void MiscRegFile::setReg(int miscReg, const MiscReg &val)
+void MiscRegFile::setRegNoEffect(int miscReg, const MiscReg &val)
 {
     switch (miscReg) {
-        case MISCREG_Y:
-          y = val;
-          break;
-        case MISCREG_CCR:
-          ccr = val;
-          break;
-        case MISCREG_ASI:
-          asi = val;
-          break;
-        case MISCREG_FPRS:
-          fprs = val;
-          break;
-        case MISCREG_TICK:
-          tick = val;
-          break;
-        case MISCREG_PCR:
-          panic("PCR not implemented\n");
-        case MISCREG_PIC:
-          panic("PIC not implemented\n");
-        case MISCREG_GSR:
-          gsr = val;
-          break;
-        case MISCREG_SOFTINT:
-          softint = val;
-          break;
-        case MISCREG_TICK_CMPR:
-          tick_cmpr = val;
-          break;
-        case MISCREG_STICK:
-          stick = val;
-          break;
-        case MISCREG_STICK_CMPR:
-          stick_cmpr = val;
-          break;
+//      case MISCREG_Y:
+//        y = val;
+//        break;
+//      case MISCREG_CCR:
+//        ccr = val;
+//        break;
+      case MISCREG_ASI:
+        asi = val;
+        break;
+      case MISCREG_FPRS:
+        fprs = val;
+        break;
+      case MISCREG_TICK:
+        tick = val;
+        break;
+      case MISCREG_PCR:
+        panic("PCR not implemented\n");
+      case MISCREG_PIC:
+        panic("PIC not implemented\n");
+      case MISCREG_GSR:
+        gsr = val;
+        break;
+      case MISCREG_SOFTINT:
+        softint = val;
+        break;
+      case MISCREG_TICK_CMPR:
+        tick_cmpr = val;
+        break;
+      case MISCREG_STICK:
+        stick = val;
+        break;
+      case MISCREG_STICK_CMPR:
+        stick_cmpr = val;
+        break;
 
         /** Privilged Registers */
-        case MISCREG_TPC:
-          tpc[tl-1] = val;
-          break;
-        case MISCREG_TNPC:
-          tnpc[tl-1] = val;
-          break;
-        case MISCREG_TSTATE:
-          tstate[tl-1] = val;
-          break;
-        case MISCREG_TT:
-          tt[tl-1] = val;
-          break;
-        case MISCREG_PRIVTICK:
-          panic("Priviliged access to tick regesiters not implemented\n");
-        case MISCREG_TBA:
-          // clear lower 7 bits on writes.
-          tba = val & ULL(~0x7FFF);
-          break;
-        case MISCREG_PSTATE:
-          pstate = (val & PSTATE_MASK);
-          break;
-        case MISCREG_TL:
-          tl = val;
-          break;
-        case MISCREG_PIL:
-          pil = val;
-          break;
-        case MISCREG_CWP:
-          cwp = val;
-          break;
-        case MISCREG_CANSAVE:
-          cansave = val;
-          break;
-        case MISCREG_CANRESTORE:
-          canrestore = val;
-          break;
-        case MISCREG_CLEANWIN:
-          cleanwin = val;
-          break;
-        case MISCREG_OTHERWIN:
-          otherwin = val;
-          break;
-        case MISCREG_WSTATE:
-          wstate = val;
-          break;
-        case MISCREG_GL:
-          gl = val;
-          break;
+      case MISCREG_TPC:
+        tpc[tl-1] = val;
+        break;
+      case MISCREG_TNPC:
+        tnpc[tl-1] = val;
+        break;
+      case MISCREG_TSTATE:
+        tstate[tl-1] = val;
+        break;
+      case MISCREG_TT:
+        tt[tl-1] = val;
+        break;
+      case MISCREG_PRIVTICK:
+        panic("Priviliged access to tick regesiters not implemented\n");
+      case MISCREG_TBA:
+        // clear lower 7 bits on writes.
+        tba = val & ULL(~0x7FFF);
+        break;
+      case MISCREG_PSTATE:
+        pstate = (val & PSTATE_MASK);
+        break;
+      case MISCREG_TL:
+        tl = val;
+        break;
+      case MISCREG_PIL:
+        pil = val;
+        break;
+      case MISCREG_CWP:
+        cwp = val;
+        break;
+//      case MISCREG_CANSAVE:
+//        cansave = val;
+//        break;
+//      case MISCREG_CANRESTORE:
+//        canrestore = val;
+//        break;
+//      case MISCREG_CLEANWIN:
+//        cleanwin = val;
+//        break;
+//      case MISCREG_OTHERWIN:
+//        otherwin = val;
+//        break;
+//      case MISCREG_WSTATE:
+//        wstate = val;
+//        break;
+      case MISCREG_GL:
+        gl = val;
+        break;
 
         /** Hyper privileged registers */
-        case MISCREG_HPSTATE:
-          hpstate = val;
-          break;
-        case MISCREG_HTSTATE:
-          htstate[tl-1] = val;
-          break;
-        case MISCREG_HINTP:
-          panic("HINTP not implemented\n");
-        case MISCREG_HTBA:
-          htba = val;
-          break;
-        case MISCREG_STRAND_STS_REG:
-          strandStatusReg = val;
-          break;
-        case MISCREG_HSTICK_CMPR:
-          hstick_cmpr = val;
-          break;
+      case MISCREG_HPSTATE:
+        hpstate = val;
+        break;
+      case MISCREG_HTSTATE:
+        htstate[tl-1] = val;
+        break;
+      case MISCREG_HINTP:
+        hintp = val;
+      case MISCREG_HTBA:
+        htba = val;
+        break;
+      case MISCREG_STRAND_STS_REG:
+        strandStatusReg = val;
+        break;
+      case MISCREG_HSTICK_CMPR:
+        hstick_cmpr = val;
+        break;
 
         /** Floating Point Status Register */
-        case MISCREG_FSR:
-          fsr = val;
-          break;
-        default:
-          panic("Miscellaneous register %d not implemented\n", miscReg);
-    }
-}
+      case MISCREG_FSR:
+        fsr = val;
+        DPRINTF(MiscRegs, "FSR written with: %#x\n", fsr);
+        break;
 
-inline void MiscRegFile::setImplicitAsis()
-{
-    //The spec seems to use trap level to indicate the privilege level of the
-    //processor. It's unclear whether the implicit ASIs should directly depend
-    //on the trap level, or if they should really be based on the privelege
-    //bits
-    if(tl == 0)
-    {
-        implicitInstAsi = implicitDataAsi =
-            (pstate & (1 << 9)) ? ASI_PRIMARY_LITTLE : ASI_PRIMARY;
-    }
-    else if(tl <= MaxPTL)
-    {
-        implicitInstAsi = ASI_NUCLEUS;
-        implicitDataAsi = (pstate & (1 << 9)) ? ASI_NUCLEUS_LITTLE : ASI_NUCLEUS;
-    }
-    else
-    {
-        //This is supposed to force physical addresses to match the spec.
-        //It might not because of context values and partition values.
-        implicitInstAsi = implicitDataAsi = ASI_REAL;
+      case MISCREG_MMU_P_CONTEXT:
+        priContext = val;
+        break;
+      case MISCREG_MMU_S_CONTEXT:
+        secContext = val;
+        break;
+      case MISCREG_MMU_PART_ID:
+        partId = val;
+        break;
+      case MISCREG_MMU_LSU_CTRL:
+        lsuCtrlReg = val;
+        break;
+
+      case MISCREG_SCRATCHPAD_R0:
+        scratchPad[0] = val;
+        break;
+      case MISCREG_SCRATCHPAD_R1:
+        scratchPad[1] = val;
+        break;
+      case MISCREG_SCRATCHPAD_R2:
+        scratchPad[2] = val;
+        break;
+      case MISCREG_SCRATCHPAD_R3:
+        scratchPad[3] = val;
+        break;
+      case MISCREG_SCRATCHPAD_R4:
+        scratchPad[4] = val;
+        break;
+      case MISCREG_SCRATCHPAD_R5:
+        scratchPad[5] = val;
+        break;
+      case MISCREG_SCRATCHPAD_R6:
+        scratchPad[6] = val;
+        break;
+      case MISCREG_SCRATCHPAD_R7:
+        scratchPad[7] = val;
+        break;
+      case MISCREG_QUEUE_CPU_MONDO_HEAD:
+        cpu_mondo_head = val;
+        break;
+      case MISCREG_QUEUE_CPU_MONDO_TAIL:
+        cpu_mondo_tail = val;
+        break;
+      case MISCREG_QUEUE_DEV_MONDO_HEAD:
+        dev_mondo_head = val;
+        break;
+      case MISCREG_QUEUE_DEV_MONDO_TAIL:
+        dev_mondo_tail = val;
+        break;
+      case MISCREG_QUEUE_RES_ERROR_HEAD:
+        res_error_head = val;
+        break;
+      case MISCREG_QUEUE_RES_ERROR_TAIL:
+        res_error_tail = val;
+        break;
+      case MISCREG_QUEUE_NRES_ERROR_HEAD:
+        nres_error_head = val;
+        break;
+      case MISCREG_QUEUE_NRES_ERROR_TAIL:
+        nres_error_tail = val;
+        break;
+      default:
+        panic("Miscellaneous register %d not implemented\n", miscReg);
     }
 }
 
-void MiscRegFile::setRegWithEffect(int miscReg,
+void MiscRegFile::setReg(int miscReg,
         const MiscReg &val, ThreadContext * tc)
 {
-    const uint64_t Bit64 = (1ULL << 63);
-#if FULL_SYSTEM
-    uint64_t time;
-    SparcSystem *sys;
-#endif
+    MiscReg new_val = val;
+
     switch (miscReg) {
-        case MISCREG_TICK:
-          tick = tc->getCpuPtr()->curCycle() - val  & ~Bit64;
-          tick |= val & Bit64;
-          break;
-        case MISCREG_FPRS:
-          //Configure the fpu based on the fprs
-          break;
-        case MISCREG_PCR:
-          //Set up performance counting based on pcr value
-          break;
-        case MISCREG_PSTATE:
-          pstate = val & PSTATE_MASK;
-          setImplicitAsis();
-          return;
-        case MISCREG_TL:
-          tl = val;
-          setImplicitAsis();
-          return;
-        case MISCREG_CWP:
-          tc->changeRegFileContext(CONTEXT_CWP, val);
-          break;
-        case MISCREG_GL:
-          tc->changeRegFileContext(CONTEXT_GLOBALS, val);
-          break;
-        case MISCREG_SOFTINT:
-          //We need to inject interrupts, and or notify the interrupt
-          //object that it needs to use a different interrupt level.
-          //Any newly appropriate interrupts will happen when the cpu gets
-          //around to checking for them. This might not be quite what we
-          //want.
-          break;
-        case MISCREG_SOFTINT_CLR:
-          //Do whatever this is supposed to do...
-          break;
-        case MISCREG_SOFTINT_SET:
-          //Do whatever this is supposed to do...
-          break;
+      case MISCREG_STICK:
+      case MISCREG_TICK:
+        // stick and tick are same thing on niagra
+        // use stick for offset and tick for holding intrrupt bit
+        stick = mbits(val,62,0) - tc->getCpuPtr()->instCount();
+        tick = mbits(val,63,63);
+        DPRINTF(Timer, "Writing TICK=%#X\n", val);
+        break;
+      case MISCREG_FPRS:
+        //Configure the fpu based on the fprs
+        break;
+      case MISCREG_PCR:
+        //Set up performance counting based on pcr value
+        break;
+      case MISCREG_PSTATE:
+        pstate = val & PSTATE_MASK;
+        return;
+      case MISCREG_TL:
+        tl = val;
 #if FULL_SYSTEM
-        case MISCREG_TICK_CMPR:
-          if (tickCompare == NULL)
-              tickCompare = new TickCompareEvent(this, tc);
-          setReg(miscReg, val);
-          if ((tick_cmpr & mask(63)) && tickCompare->scheduled())
-                  tickCompare->deschedule();
-          time = (tick_cmpr & mask(63)) - (tick & mask(63));
-          if (!(tick_cmpr & ~mask(63)) && time > 0)
-              tickCompare->schedule(time * tc->getCpuPtr()->cycles(1));
-          break;
+        if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv))
+            tc->getCpuPtr()->postInterrupt(IT_TRAP_LEVEL_ZERO, 0);
+        else
+            tc->getCpuPtr()->clearInterrupt(IT_TRAP_LEVEL_ZERO, 0);
 #endif
-        case MISCREG_PIL:
-          //We need to inject interrupts, and or notify the interrupt
-          //object that it needs to use a different interrupt level.
-          //Any newly appropriate interrupts will happen when the cpu gets
-          //around to checking for them. This might not be quite what we
-          //want.
-          break;
-//We'll include this only in FS so we don't need the SparcSystem type around
-//in SE.
+        return;
+      case MISCREG_CWP:
+        new_val = val >= NWindows ? NWindows - 1 : val;
+        if (val >= NWindows)
+            new_val = NWindows - 1;
+        break;
+      case MISCREG_GL:
+        break;
+      case MISCREG_PIL:
+      case MISCREG_SOFTINT:
+      case MISCREG_SOFTINT_SET:
+      case MISCREG_SOFTINT_CLR:
+      case MISCREG_TICK_CMPR:
+      case MISCREG_STICK_CMPR:
+      case MISCREG_HINTP:
+      case MISCREG_HTSTATE:
+      case MISCREG_HTBA:
+      case MISCREG_HVER:
+      case MISCREG_STRAND_STS_REG:
+      case MISCREG_HSTICK_CMPR:
+      case MISCREG_QUEUE_CPU_MONDO_HEAD:
+      case MISCREG_QUEUE_CPU_MONDO_TAIL:
+      case MISCREG_QUEUE_DEV_MONDO_HEAD:
+      case MISCREG_QUEUE_DEV_MONDO_TAIL:
+      case MISCREG_QUEUE_RES_ERROR_HEAD:
+      case MISCREG_QUEUE_RES_ERROR_TAIL:
+      case MISCREG_QUEUE_NRES_ERROR_HEAD:
+      case MISCREG_QUEUE_NRES_ERROR_TAIL:
 #if FULL_SYSTEM
-        case MISCREG_STICK:
-          sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
-          assert(sys != NULL);
-          sys->sysTick = curTick/Clock::Int::ns - val & ~Bit64;
-          stick |= val & Bit64;
-          break;
-        case MISCREG_STICK_CMPR:
-          if (sTickCompare == NULL)
-              sTickCompare = new STickCompareEvent(this, tc);
-          sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
-          assert(sys != NULL);
-          if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled())
-                  sTickCompare->deschedule();
-          time = (stick_cmpr & mask(63)) - sys->sysTick;
-          if (!(stick_cmpr & ~mask(63)) && time > 0)
-              sTickCompare->schedule(time * Clock::Int::ns);
-          break;
-        case MISCREG_HSTICK_CMPR:
-          if (hSTickCompare == NULL)
-              hSTickCompare = new HSTickCompareEvent(this, tc);
-          sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
-          assert(sys != NULL);
-          if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled())
-                  hSTickCompare->deschedule();
-          int64_t time = (hstick_cmpr & mask(63)) - sys->sysTick;
-          if (!(hstick_cmpr & ~mask(63)) && time > 0)
-              hSTickCompare->schedule(time * Clock::Int::ns);
-          break;
+      case MISCREG_HPSTATE:
+        setFSReg(miscReg, val, tc);
+        return;
+#else
+      case MISCREG_HPSTATE:
+        //HPSTATE is special because normal trap processing saves HPSTATE when
+        //it goes into a trap, and restores it when it returns.
+        return;
+      panic("Accessing Fullsystem register %s to %#x in SE mode\n",
+            getMiscRegName(miscReg), val);
 #endif
     }
-    setReg(miscReg, val);
+    setRegNoEffect(miscReg, new_val);
 }
 
-void MiscRegFile::serialize(std::ostream & os)
+void
+MiscRegFile::serialize(EventManager *em, std::ostream &os)
 {
-    SERIALIZE_SCALAR(pstate);
-    SERIALIZE_SCALAR(tba);
-    SERIALIZE_SCALAR(y);
-    SERIALIZE_SCALAR(pil);
-    SERIALIZE_SCALAR(gl);
-    SERIALIZE_SCALAR(cwp);
-    SERIALIZE_ARRAY(tt, MaxTL);
-    SERIALIZE_SCALAR(ccr);
     SERIALIZE_SCALAR(asi);
-    SERIALIZE_SCALAR(tl);
-    SERIALIZE_ARRAY(tpc, MaxTL);
-    SERIALIZE_ARRAY(tnpc, MaxTL);
-    SERIALIZE_ARRAY(tstate, MaxTL);
     SERIALIZE_SCALAR(tick);
-    SERIALIZE_SCALAR(cansave);
-    SERIALIZE_SCALAR(canrestore);
-    SERIALIZE_SCALAR(otherwin);
-    SERIALIZE_SCALAR(cleanwin);
-    SERIALIZE_SCALAR(wstate);
-    SERIALIZE_SCALAR(fsr);
     SERIALIZE_SCALAR(fprs);
+    SERIALIZE_SCALAR(gsr);
+    SERIALIZE_SCALAR(softint);
+    SERIALIZE_SCALAR(tick_cmpr);
+    SERIALIZE_SCALAR(stick);
+    SERIALIZE_SCALAR(stick_cmpr);
+    SERIALIZE_ARRAY(tpc,MaxTL);
+    SERIALIZE_ARRAY(tnpc,MaxTL);
+    SERIALIZE_ARRAY(tstate,MaxTL);
+    SERIALIZE_ARRAY(tt,MaxTL);
+    SERIALIZE_SCALAR(tba);
+    SERIALIZE_SCALAR(pstate);
+    SERIALIZE_SCALAR(tl);
+    SERIALIZE_SCALAR(pil);
+    SERIALIZE_SCALAR(cwp);
+    SERIALIZE_SCALAR(gl);
     SERIALIZE_SCALAR(hpstate);
-    SERIALIZE_ARRAY(htstate, MaxTL);
+    SERIALIZE_ARRAY(htstate,MaxTL);
+    SERIALIZE_SCALAR(hintp);
     SERIALIZE_SCALAR(htba);
     SERIALIZE_SCALAR(hstick_cmpr);
-    SERIALIZE_SCALAR((int)implicitInstAsi);
-    SERIALIZE_SCALAR((int)implicitDataAsi);
+    SERIALIZE_SCALAR(strandStatusReg);
+    SERIALIZE_SCALAR(fsr);
+    SERIALIZE_SCALAR(priContext);
+    SERIALIZE_SCALAR(secContext);
+    SERIALIZE_SCALAR(partId);
+    SERIALIZE_SCALAR(lsuCtrlReg);
+    SERIALIZE_ARRAY(scratchPad,8);
+    SERIALIZE_SCALAR(cpu_mondo_head);
+    SERIALIZE_SCALAR(cpu_mondo_tail);
+    SERIALIZE_SCALAR(dev_mondo_head);
+    SERIALIZE_SCALAR(dev_mondo_tail);
+    SERIALIZE_SCALAR(res_error_head);
+    SERIALIZE_SCALAR(res_error_tail);
+    SERIALIZE_SCALAR(nres_error_head);
+    SERIALIZE_SCALAR(nres_error_tail);
+#if FULL_SYSTEM
+    Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0;
+    ThreadContext *tc = NULL;
+    BaseCPU *cpu = NULL;
+    int tc_num = 0;
+    bool tick_intr_sched = true;
+
+    if (tickCompare)
+        tc = tickCompare->getTC();
+    else if (sTickCompare)
+        tc = sTickCompare->getTC();
+    else if (hSTickCompare)
+        tc = hSTickCompare->getTC();
+    else
+        tick_intr_sched = false;
+
+    SERIALIZE_SCALAR(tick_intr_sched);
+
+    if (tc) {
+        cpu = tc->getCpuPtr();
+        tc_num = cpu->findContext(tc);
+        if (tickCompare && tickCompare->scheduled())
+            tick_cmp = tickCompare->when();
+        if (sTickCompare && sTickCompare->scheduled())
+            stick_cmp = sTickCompare->when();
+        if (hSTickCompare && hSTickCompare->scheduled())
+            hstick_cmp = hSTickCompare->when();
+
+        SERIALIZE_OBJPTR(cpu);
+        SERIALIZE_SCALAR(tc_num);
+        SERIALIZE_SCALAR(tick_cmp);
+        SERIALIZE_SCALAR(stick_cmp);
+        SERIALIZE_SCALAR(hstick_cmp);
+    }
+#endif
 }
 
-void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section)
+void
+MiscRegFile::unserialize(EventManager *em, Checkpoint *cp,
+    const string &section)
 {
-    UNSERIALIZE_SCALAR(pstate);
-    UNSERIALIZE_SCALAR(tba);
-    UNSERIALIZE_SCALAR(y);
-    UNSERIALIZE_SCALAR(pil);
-    UNSERIALIZE_SCALAR(gl);
-    UNSERIALIZE_SCALAR(cwp);
-    UNSERIALIZE_ARRAY(tt, MaxTL);
-    UNSERIALIZE_SCALAR(ccr);
     UNSERIALIZE_SCALAR(asi);
-    UNSERIALIZE_SCALAR(tl);
-    UNSERIALIZE_ARRAY(tpc, MaxTL);
-    UNSERIALIZE_ARRAY(tnpc, MaxTL);
-    UNSERIALIZE_ARRAY(tstate, MaxTL);
     UNSERIALIZE_SCALAR(tick);
-    UNSERIALIZE_SCALAR(cansave);
-    UNSERIALIZE_SCALAR(canrestore);
-    UNSERIALIZE_SCALAR(otherwin);
-    UNSERIALIZE_SCALAR(cleanwin);
-    UNSERIALIZE_SCALAR(wstate);
-    UNSERIALIZE_SCALAR(fsr);
     UNSERIALIZE_SCALAR(fprs);
+    UNSERIALIZE_SCALAR(gsr);
+    UNSERIALIZE_SCALAR(softint);
+    UNSERIALIZE_SCALAR(tick_cmpr);
+    UNSERIALIZE_SCALAR(stick);
+    UNSERIALIZE_SCALAR(stick_cmpr);
+    UNSERIALIZE_ARRAY(tpc,MaxTL);
+    UNSERIALIZE_ARRAY(tnpc,MaxTL);
+    UNSERIALIZE_ARRAY(tstate,MaxTL);
+    UNSERIALIZE_ARRAY(tt,MaxTL);
+    UNSERIALIZE_SCALAR(tba);
+    UNSERIALIZE_SCALAR(pstate);
+    UNSERIALIZE_SCALAR(tl);
+    UNSERIALIZE_SCALAR(pil);
+    UNSERIALIZE_SCALAR(cwp);
+    UNSERIALIZE_SCALAR(gl);
     UNSERIALIZE_SCALAR(hpstate);
-    UNSERIALIZE_ARRAY(htstate, MaxTL);
+    UNSERIALIZE_ARRAY(htstate,MaxTL);
+    UNSERIALIZE_SCALAR(hintp);
     UNSERIALIZE_SCALAR(htba);
     UNSERIALIZE_SCALAR(hstick_cmpr);
-    int temp;
-    UNSERIALIZE_SCALAR(temp);
-    implicitInstAsi = (ASI)temp;
-    UNSERIALIZE_SCALAR(temp);
-    implicitDataAsi = (ASI)temp;
-}
+    UNSERIALIZE_SCALAR(strandStatusReg);
+    UNSERIALIZE_SCALAR(fsr);
+    UNSERIALIZE_SCALAR(priContext);
+    UNSERIALIZE_SCALAR(secContext);
+    UNSERIALIZE_SCALAR(partId);
+    UNSERIALIZE_SCALAR(lsuCtrlReg);
+    UNSERIALIZE_ARRAY(scratchPad,8);
+    UNSERIALIZE_SCALAR(cpu_mondo_head);
+    UNSERIALIZE_SCALAR(cpu_mondo_tail);
+    UNSERIALIZE_SCALAR(dev_mondo_head);
+    UNSERIALIZE_SCALAR(dev_mondo_tail);
+    UNSERIALIZE_SCALAR(res_error_head);
+    UNSERIALIZE_SCALAR(res_error_tail);
+    UNSERIALIZE_SCALAR(nres_error_head);
+    UNSERIALIZE_SCALAR(nres_error_tail);
 
 #if FULL_SYSTEM
-void
-MiscRegFile::processTickCompare(ThreadContext *tc)
-{
-    panic("tick compare not implemented\n");
-}
+    Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0;
+    ThreadContext *tc = NULL;
+    BaseCPU *cpu = NULL;
+    int tc_num;
+    bool tick_intr_sched;
+    UNSERIALIZE_SCALAR(tick_intr_sched);
+    if (tick_intr_sched) {
+        UNSERIALIZE_OBJPTR(cpu);
+        if (cpu) {
+            UNSERIALIZE_SCALAR(tc_num);
+            UNSERIALIZE_SCALAR(tick_cmp);
+            UNSERIALIZE_SCALAR(stick_cmp);
+            UNSERIALIZE_SCALAR(hstick_cmp);
+            tc = cpu->getContext(tc_num);
 
-void
-MiscRegFile::processSTickCompare(ThreadContext *tc)
-{
-    panic("tick compare not implemented\n");
-}
+            if (tick_cmp) {
+                tickCompare = new TickCompareEvent(this, tc);
+                em->schedule(tickCompare, tick_cmp);
+            }
+            if (stick_cmp)  {
+                sTickCompare = new STickCompareEvent(this, tc);
+                em->schedule(sTickCompare, stick_cmp);
+            }
+            if (hstick_cmp)  {
+                hSTickCompare = new HSTickCompareEvent(this, tc);
+                em->schedule(hSTickCompare, hstick_cmp);
+            }
+        }
+    }
 
-void
-MiscRegFile::processHSTickCompare(ThreadContext *tc)
-{
-    panic("tick compare not implemented\n");
+ #endif
 }
-#endif