* 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"
+#if FULL_SYSTEM
+#include "arch/sparc/system.hh"
+#endif
+
using namespace SparcISA;
using namespace std;
string SparcISA::getMiscRegName(RegIndex index)
{
static::string miscRegName[NumMiscRegs] =
- {"y", "ccr", "asi", "tick", "pc", "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",
return miscRegName[index];
}
-#if FULL_SYSTEM
-
-//XXX These need an implementation someplace
-/** Fullsystem only register version of ReadRegWithEffect() */
-MiscReg MiscRegFile::readFSRegWithEffect(int miscReg, ThreadContext *tc);
-/** Fullsystem only register version of SetRegWithEffect() */
-void MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
- ThreadContext * tc);
-#endif
+enum RegMask
+{
+ PSTATE_MASK = (((1 << 4) - 1) << 1) | (((1 << 4) - 1) << 6) | (1 << 12)
+};
void MiscRegFile::reset()
{
- //pstateFields.pef = 0; //No FPU
- //pstateFields.pef = 1; //FPU
-#if FULL_SYSTEM
- //For SPARC, when a system is first started, there is a power
- //on reset Trap which sets the processor into the following state.
- //Bits that aren't set aren't defined on startup.
- //XXX this code should be moved into the POR fault.
- tl = MaxTL;
- gl = MaxGL;
-
- tickFields.counter = 0; //The TICK register is unreadable bya
- tickFields.npt = 1; //The TICK register is unreadable by by !priv
-
- softint = 0; // Clear all the soft interrupt bits
- tick_cmprFields.int_dis = 1; // disable timer compare interrupts
- tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
- stickFields.npt = 1; //The TICK register is unreadable by by !priv
- stick_cmprFields.int_dis = 1; // disable timer compare interrupts
- stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
-
-
- tt[tl] = power_on_reset;
- pstate = 0; // fields 0 but pef
- pstateFields.pef = 1;
-
- hpstate = 0;
- hpstateFields.red = 1;
- hpstateFields.hpriv = 1;
- hpstateFields.tlz = 0; // this is a guess
- hintp = 0; // no interrupts pending
- hstick_cmprFields.int_dis = 1; // disable timer compare interrupts
- hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
-#endif
+ y = 0;
+ ccr = 0;
+ asi = 0;
+ tick = 0;
+ 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;
+ implicitInstAsi = ASI_PRIMARY;
+ implicitDataAsi = ASI_PRIMARY;
}
MiscReg MiscRegFile::readReg(int miscReg)
case MISCREG_TICK:
return tick;
case MISCREG_PCR:
+ panic("PCR not implemented\n");
case MISCREG_PIC:
- panic("ASR number %d not implemented\n", miscReg - AsrStart);
+ panic("PIC not implemented\n");
case MISCREG_GSR:
return gsr;
case MISCREG_SOFTINT:
switch (miscReg) {
case MISCREG_TICK:
case MISCREG_PRIVTICK:
- return tc->getCpuPtr()->curCycle() - tickFields.counter |
- tickFields.npt << 63;
+ 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.
+#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
+ case MISCREG_HVER:
+ return NWindows | MaxTL << 8 | MaxGL << 16;
}
return readReg(miscReg);
}
tick = val;
break;
case MISCREG_PCR:
+ panic("PCR not implemented\n");
case MISCREG_PIC:
- panic("ASR number %d not implemented\n", miscReg - AsrStart);
+ panic("PIC not implemented\n");
case MISCREG_GSR:
gsr = val;
break;
tba = val & ULL(~0x7FFF);
break;
case MISCREG_PSTATE:
- pstate = val;
+ pstate = (val & PSTATE_MASK);
break;
case MISCREG_TL:
tl = val;
if(tl == 0)
{
implicitInstAsi = implicitDataAsi =
- pstateFields.cle ? ASI_PRIMARY_LITTLE : ASI_PRIMARY;
+ (pstate & (1 << 9)) ? ASI_PRIMARY_LITTLE : ASI_PRIMARY;
}
else if(tl <= MaxPTL)
{
implicitInstAsi = ASI_NUCLEUS;
- implicitDataAsi = pstateFields.cle ? ASI_NUCLEUS_LITTLE : ASI_NUCLEUS;
+ implicitDataAsi = (pstate & (1 << 9)) ? ASI_NUCLEUS_LITTLE : ASI_NUCLEUS;
}
else
{
const MiscReg &val, ThreadContext * tc)
{
const uint64_t Bit64 = (1ULL << 63);
+#if FULL_SYSTEM
+ uint64_t time;
+ SparcSystem *sys;
+#endif
switch (miscReg) {
case MISCREG_TICK:
- tickFields.counter = tc->getCpuPtr()->curCycle() - val & ~Bit64;
- tickFields.npt = val & Bit64 ? 1 : 0;
+ tick = tc->getCpuPtr()->curCycle() - val & ~Bit64;
+ tick |= val & Bit64;
break;
case MISCREG_FPRS:
//Configure the fpu based on the fprs
//Set up performance counting based on pcr value
break;
case MISCREG_PSTATE:
- pstate = val;
+ pstate = val & PSTATE_MASK;
setImplicitAsis();
return;
case MISCREG_TL:
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;
+#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;
+#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.
+#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;
+#endif
}
setReg(miscReg, val);
}
implicitDataAsi = (ASI)temp;
}
+#if FULL_SYSTEM
+void
+MiscRegFile::processTickCompare(ThreadContext *tc)
+{
+ panic("tick compare not implemented\n");
+}
+
+void
+MiscRegFile::processSTickCompare(ThreadContext *tc)
+{
+ panic("tick compare not implemented\n");
+}
+
+void
+MiscRegFile::processHSTickCompare(ThreadContext *tc)
+{
+ panic("tick compare not implemented\n");
+}
+#endif