/* * Copyright (c) 2003-2005 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. * * Authors: Gabe Black * Ali Saidi */ #include "arch/sparc/asi.hh" #include "arch/sparc/miscregfile.hh" #include "base/bitfield.hh" #include "base/trace.hh" #include "config/full_system.hh" #include "cpu/base.hh" #include "cpu/thread_context.hh" using namespace SparcISA; using namespace std; class Checkpoint; //These functions map register indices to names string SparcISA::getMiscRegName(RegIndex index) { static::string miscRegName[NumMiscRegs] = {/*"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", "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg", "hstick_cmpr", "fsr"}; return miscRegName[index]; } enum RegMask { PSTATE_MASK = (((1 << 4) - 1) << 1) | (((1 << 4) - 1) << 6) | (1 << 12) }; void MiscRegFile::clear() { //y = 0; //ccr = 0; asi = 0; tick = ULL(1) << 63; fprs = 0; gsr = 0; softint = 0; tick_cmpr = 0; stick = 0; stick_cmpr = 0; memset(tpc, 0, sizeof(tpc)); memset(tnpc, 0, sizeof(tnpc)); memset(tstate, 0, sizeof(tstate)); memset(tt, 0, sizeof(tt)); pstate = 0; tl = 0; pil = 0; cwp = 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); memset(htstate, 0, sizeof(htstate)); hintp = 0; htba = 0; hstick_cmpr = 0; //This is set this way in Legion for some reason strandStatusReg = 0x50000; fsr = 0; priContext = 0; secContext = 0; partId = 0; lsuCtrlReg = 0; iTlbC0TsbPs0 = 0; iTlbC0TsbPs1 = 0; iTlbC0Config = 0; iTlbCXTsbPs0 = 0; iTlbCXTsbPs1 = 0; iTlbCXConfig = 0; iTlbSfsr = 0; iTlbTagAccess = 0; dTlbC0TsbPs0 = 0; dTlbC0TsbPs1 = 0; dTlbC0Config = 0; dTlbCXTsbPs0 = 0; dTlbCXTsbPs1 = 0; dTlbCXConfig = 0; dTlbSfsr = 0; dTlbSfar = 0; dTlbTagAccess = 0; memset(scratchPad, 0, sizeof(scratchPad)); #if FULL_SYSTEM tickCompare = NULL; sTickCompare = NULL; hSTickCompare = NULL; #endif } MiscReg MiscRegFile::readReg(int miscReg) { switch (miscReg) { case 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; //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; /** Hyper privileged registers */ case MISCREG_HPSTATE: return hpstate; case MISCREG_HTSTATE: return htstate[tl-1]; case MISCREG_HINTP: return hintp; 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; /** Floating Point Status Register */ case MISCREG_FSR: DPRINTF(Sparc, "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_MMU_ITLB_C0_TSB_PS0: return iTlbC0TsbPs0; case MISCREG_MMU_ITLB_C0_TSB_PS1: return iTlbC0TsbPs1; case MISCREG_MMU_ITLB_C0_CONFIG: return iTlbC0Config; case MISCREG_MMU_ITLB_CX_TSB_PS0: return iTlbCXTsbPs0; case MISCREG_MMU_ITLB_CX_TSB_PS1: return iTlbCXTsbPs1; case MISCREG_MMU_ITLB_CX_CONFIG: return iTlbCXConfig; case MISCREG_MMU_ITLB_SFSR: return iTlbSfsr; case MISCREG_MMU_ITLB_TAG_ACCESS: return iTlbTagAccess; case MISCREG_MMU_DTLB_C0_TSB_PS0: return dTlbC0TsbPs0; case MISCREG_MMU_DTLB_C0_TSB_PS1: return dTlbC0TsbPs1; case MISCREG_MMU_DTLB_C0_CONFIG: return dTlbC0Config; case MISCREG_MMU_DTLB_CX_TSB_PS0: return dTlbCXTsbPs0; case MISCREG_MMU_DTLB_CX_TSB_PS1: return dTlbCXTsbPs1; case MISCREG_MMU_DTLB_CX_CONFIG: return dTlbCXConfig; case MISCREG_MMU_DTLB_SFSR: return dTlbSfsr; case MISCREG_MMU_DTLB_SFAR: return dTlbSfar; case MISCREG_MMU_DTLB_TAG_ACCESS: return dTlbTagAccess; 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) { switch (miscReg) { // 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_HPSTATE: return readFSRegWithEffect(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 } return readReg(miscReg); } void MiscRegFile::setReg(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; /** 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; /** Hyper privileged registers */ 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; DPRINTF(Sparc, "FSR written with: %#x\n", fsr); break; 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_MMU_ITLB_C0_TSB_PS0: iTlbC0TsbPs0 = val; break; case MISCREG_MMU_ITLB_C0_TSB_PS1: iTlbC0TsbPs1 = val; break; case MISCREG_MMU_ITLB_C0_CONFIG: iTlbC0Config = val; break; case MISCREG_MMU_ITLB_CX_TSB_PS0: iTlbCXTsbPs0 = val; break; case MISCREG_MMU_ITLB_CX_TSB_PS1: iTlbCXTsbPs1 = val; break; case MISCREG_MMU_ITLB_CX_CONFIG: iTlbCXConfig = val; break; case MISCREG_MMU_ITLB_SFSR: iTlbSfsr = val; break; case MISCREG_MMU_ITLB_TAG_ACCESS: iTlbTagAccess = val; break; case MISCREG_MMU_DTLB_C0_TSB_PS0: dTlbC0TsbPs0 = val; break; case MISCREG_MMU_DTLB_C0_TSB_PS1: dTlbC0TsbPs1 = val; break; case MISCREG_MMU_DTLB_C0_CONFIG: dTlbC0Config = val; break; case MISCREG_MMU_DTLB_CX_TSB_PS0: dTlbCXTsbPs0 = val; break; case MISCREG_MMU_DTLB_CX_TSB_PS1: dTlbCXTsbPs1 = val; break; case MISCREG_MMU_DTLB_CX_CONFIG: dTlbCXConfig = val; break; case MISCREG_MMU_DTLB_SFSR: dTlbSfsr = val; break; case MISCREG_MMU_DTLB_SFAR: dTlbSfar = val; break; case MISCREG_MMU_DTLB_TAG_ACCESS: dTlbTagAccess = 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, const MiscReg &val, ThreadContext * tc) { MiscReg new_val = val; switch (miscReg) { 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; return; case MISCREG_CWP: new_val = val > NWindows ? NWindows - 1 : val; tc->changeRegFileContext(CONTEXT_CWP, new_val); break; case MISCREG_GL: tc->changeRegFileContext(CONTEXT_GLOBALS, val); 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_HPSTATE: setFSRegWithEffect(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, new_val); } void MiscRegFile::serialize(std::ostream & os) { SERIALIZE_SCALAR(asi); SERIALIZE_SCALAR(tick); 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_SCALAR(hintp); SERIALIZE_SCALAR(htba); SERIALIZE_SCALAR(hstick_cmpr); SERIALIZE_SCALAR(strandStatusReg); SERIALIZE_SCALAR(fsr); SERIALIZE_SCALAR(priContext); SERIALIZE_SCALAR(secContext); SERIALIZE_SCALAR(partId); SERIALIZE_SCALAR(lsuCtrlReg); SERIALIZE_SCALAR(iTlbC0TsbPs0); SERIALIZE_SCALAR(iTlbC0TsbPs1); SERIALIZE_SCALAR(iTlbC0Config); SERIALIZE_SCALAR(iTlbCXTsbPs0); SERIALIZE_SCALAR(iTlbCXTsbPs1); SERIALIZE_SCALAR(iTlbCXConfig); SERIALIZE_SCALAR(iTlbSfsr); SERIALIZE_SCALAR(iTlbTagAccess); SERIALIZE_SCALAR(dTlbC0TsbPs0); SERIALIZE_SCALAR(dTlbC0TsbPs1); SERIALIZE_SCALAR(dTlbC0Config); SERIALIZE_SCALAR(dTlbCXTsbPs0); SERIALIZE_SCALAR(dTlbCXTsbPs1); SERIALIZE_SCALAR(dTlbCXConfig); SERIALIZE_SCALAR(dTlbSfsr); SERIALIZE_SCALAR(dTlbSfar); SERIALIZE_SCALAR(dTlbTagAccess); 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) { UNSERIALIZE_SCALAR(asi); UNSERIALIZE_SCALAR(tick); 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_SCALAR(hintp); UNSERIALIZE_SCALAR(htba); UNSERIALIZE_SCALAR(hstick_cmpr); UNSERIALIZE_SCALAR(strandStatusReg); UNSERIALIZE_SCALAR(fsr); UNSERIALIZE_SCALAR(priContext); UNSERIALIZE_SCALAR(secContext); UNSERIALIZE_SCALAR(partId); UNSERIALIZE_SCALAR(lsuCtrlReg); UNSERIALIZE_SCALAR(iTlbC0TsbPs0); UNSERIALIZE_SCALAR(iTlbC0TsbPs1); UNSERIALIZE_SCALAR(iTlbC0Config); UNSERIALIZE_SCALAR(iTlbCXTsbPs0); UNSERIALIZE_SCALAR(iTlbCXTsbPs1); UNSERIALIZE_SCALAR(iTlbCXConfig); UNSERIALIZE_SCALAR(iTlbSfsr); UNSERIALIZE_SCALAR(iTlbTagAccess); UNSERIALIZE_SCALAR(dTlbC0TsbPs0); UNSERIALIZE_SCALAR(dTlbC0TsbPs1); UNSERIALIZE_SCALAR(dTlbC0Config); UNSERIALIZE_SCALAR(dTlbCXTsbPs0); UNSERIALIZE_SCALAR(dTlbCXTsbPs1); UNSERIALIZE_SCALAR(dTlbCXConfig); UNSERIALIZE_SCALAR(dTlbSfsr); UNSERIALIZE_SCALAR(dTlbSfar); UNSERIALIZE_SCALAR(dTlbTagAccess); 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 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); if (tick_cmp) { tickCompare = new TickCompareEvent(this, tc); tickCompare->schedule(tick_cmp); } if (stick_cmp) { sTickCompare = new STickCompareEvent(this, tc); sTickCompare->schedule(stick_cmp); } if (hstick_cmp) { hSTickCompare = new HSTickCompareEvent(this, tc); hSTickCompare->schedule(hstick_cmp); } } } #endif }