diff --git a/src/arch/sparc/SConscript b/src/arch/sparc/SConscript index a0a6112de..c2ef97bfa 100644 --- a/src/arch/sparc/SConscript +++ b/src/arch/sparc/SConscript @@ -60,6 +60,7 @@ full_system_sources = Split(''' stacktrace.cc system.cc tlb.cc + ua2005.cc vtophys.cc ''') diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh index e7779d333..916c23028 100644 --- a/src/arch/sparc/miscregfile.hh +++ b/src/arch/sparc/miscregfile.hh @@ -213,6 +213,10 @@ namespace SparcISA // These need to check the int_dis field and if 0 then // set appropriate bit in softint and checkinterrutps on the cpu #if FULL_SYSTEM + void setFSRegWithEffect(int miscReg, const MiscReg &val, + ThreadContext *tc); + MiscReg readFSRegWithEffect(int miscReg, ThreadContext * tc); + /** Process a tick compare event and generate an interrupt on the cpu if * appropriate. */ void processTickCompare(ThreadContext *tc); diff --git a/src/arch/sparc/mmaped_ipr.hh b/src/arch/sparc/mmaped_ipr.hh index d87d127b0..b11c16754 100644 --- a/src/arch/sparc/mmaped_ipr.hh +++ b/src/arch/sparc/mmaped_ipr.hh @@ -37,6 +37,7 @@ * ISA-specific helper functions for memory mapped IPR accesses. */ +#include "config/full_system.hh" #include "cpu/thread_context.hh" #include "mem/packet.hh" #include "arch/sparc/tlb.hh" @@ -47,14 +48,22 @@ namespace SparcISA inline Tick handleIprRead(ThreadContext *xc, Packet *pkt) { +#if FULL_SYSTEM return xc->getDTBPtr()->doMmuRegRead(xc, pkt); +#else + panic("Shouldn't have a memory mapped register in SE\n"); +#endif } inline Tick handleIprWrite(ThreadContext *xc, Packet *pkt) { +#if FULL_SYSTEM return xc->getDTBPtr()->doMmuRegWrite(xc, pkt); +#else + panic("Shouldn't have a memory mapped register in SE\n"); +#endif } diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc index 6493ddfd5..32bc2a44b 100644 --- a/src/arch/sparc/ua2005.cc +++ b/src/arch/sparc/ua2005.cc @@ -28,27 +28,32 @@ * Authors: Ali Saidi */ -#include "arch/sparc/regfile.hh" +#include "arch/sparc/miscregfile.hh" +#include "base/bitfield.hh" +#include "base/trace.hh" +#include "cpu/base.hh" +#include "cpu/thread_context.hh" -Fault -SparcISA::MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, +using namespace SparcISA; + +void +MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, ThreadContext *tc) { int64_t time; - SparcSystem *sys; + int oldLevel, newLevel; switch (miscReg) { /* Full system only ASRs */ case MISCREG_SOFTINT: - if (isNonPriv()) - return new PrivilegedOpcode; // Check if we are going to interrupt because of something - int oldLevel = InterruptLevel(softint); - int newLevel = InterruptLevel(val); + oldLevel = InterruptLevel(softint); + newLevel = InterruptLevel(val); setReg(miscReg, val); if (newLevel > oldLevel) ; // MUST DO SOMETHING HERE TO TELL CPU TO LOOK FOR INTERRUPTS XXX //tc->getCpuPtr()->checkInterrupts = true; - return NoFault; + panic("SOFTINT not implemented\n"); + break; case MISCREG_SOFTINT_CLR: return setRegWithEffect(miscReg, ~val & softint, tc); @@ -56,152 +61,100 @@ SparcISA::MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, return setRegWithEffect(miscReg, val | softint, tc); case MISCREG_TICK_CMPR: - if (isNonPriv()) - return new PrivilegedOpcode; if (tickCompare == NULL) tickCompare = new TickCompareEvent(this, tc); setReg(miscReg, val); - if (tick_cmprFields.int_dis && tickCompare.scheduled()) - tickCompare.deschedule(); - time = tick_cmprFields.tick_cmpr - tickFields.counter; - if (!tick_cmprFields.int_dis && time > 0) - tickCompare.schedule(time * tc->getCpuPtr()->cycles(1)); - return NoFault; - - case MISCREG_STICK: - if (isNonPriv()) - return new PrivilegedOpcode; - if (isPriv()) - return new PrivilegedAction; - sys = dynamic_cast(tc->getSystemPtr()); - assert(sys != NULL); - sys->sysTick = curTick/Clock::Int::ns - val & ~Bit64; - stickFields.npt = val & Bit64 ? 1 : 0; - return NoFault; + 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; case MISCREG_STICK_CMPR: - if (isNonPriv()) - return new PrivilegedOpcode; if (sTickCompare == NULL) sTickCompare = new STickCompareEvent(this, tc); - sys = dynamic_cast(tc->getSystemPtr()); - assert(sys != NULL); setReg(miscReg, val); - if (stick_cmprFields.int_dis && sTickCompare.scheduled()) - sTickCompare.deschedule(); - time = stick_cmprFields.tick_cmpr - sys->sysTick; - if (!stick_cmprFields.int_dis && time > 0) - sTickCompare.schedule(time * Clock::Int::ns); - return NoFault; + if ((stick_cmpr & mask(63)) && sTickCompare->scheduled()) + sTickCompare->deschedule(); + time = (stick_cmpr & mask(63)) - (stick & mask(63)); + if (!(stick_cmpr & ~mask(63)) && time > 0) + sTickCompare->schedule(time * tc->getCpuPtr()->cycles(1)); + break; - /* Fullsystem only Priv registers. */ case MISCREG_PIL: - if (FULL_SYSTEM) { - setReg(miscReg, val); - //tc->getCpuPtr()->checkInterrupts; - // MUST DO SOMETHING HERE TO TELL CPU TO LOOK FOR INTERRUPTS XXX - return NoFault; - } else - panic("PIL not implemented for syscall emulation\n"); + setReg(miscReg, val); + //tc->getCpuPtr()->checkInterrupts; + // MUST DO SOMETHING HERE TO TELL CPU TO LOOK FOR INTERRUPTS XXX + panic("PIL not implemented\n"); + break; - /* Hyper privileged registers */ - case MISCREG_HPSTATE: - case MISCREG_HINTP: - setReg(miscReg, val); - return NoFault; - case MISCREG_HTSTATE: - if (tl == 0) - return new IllegalInstruction; - setReg(miscReg, val); - return NoFault; + case MISCREG_HVER: + panic("Shouldn't be writing HVER\n"); case MISCREG_HTBA: // clear lower 7 bits on writes. setReg(miscReg, val & ULL(~0x7FFF)); - return NoFault; + break; - case MISCREG_STRAND_STS_REG: - setReg(miscReg, strandStatusReg); - return NoFault; case MISCREG_HSTICK_CMPR: - if (isNonPriv()) - return new PrivilegedOpcode; if (hSTickCompare == NULL) hSTickCompare = new HSTickCompareEvent(this, tc); - sys = dynamic_cast(tc->getSystemPtr()); - assert(sys != NULL); setReg(miscReg, val); - if (hstick_cmprFields.int_dis && hSTickCompare.scheduled()) - hSTickCompare.deschedule(); - int64_t time = hstick_cmprFields.tick_cmpr - sys->sysTick; - if (!hstick_cmprFields.int_dis && time > 0) - hSTickCompare.schedule(time * Clock::Int::ns); - return NoFault; + if ((hstick_cmpr & mask(63)) && hSTickCompare->scheduled()) + hSTickCompare->deschedule(); + time = (hstick_cmpr & mask(63)) - (stick & mask(63)); + if (!(hstick_cmpr & ~mask(63)) && time > 0) + hSTickCompare->schedule(time * tc->getCpuPtr()->cycles(1)); + break; + + case MISCREG_HPSTATE: + case MISCREG_HTSTATE: + case MISCREG_STRAND_STS_REG: + setReg(miscReg, val); + break; + default: - return new IllegalInstruction; + panic("Invalid write to FS misc register\n"); } } MiscReg -MiscRegFile::readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext * tc) +MiscRegFile::readFSRegWithEffect(int miscReg, ThreadContext * tc) { switch (miscReg) { /* Privileged registers. */ case MISCREG_SOFTINT: - if (isNonPriv()) { - fault = new PrivilegedOpcode; - return 0; - } - return readReg(miscReg); case MISCREG_TICK_CMPR: - if (isNonPriv()) { - fault = new PrivilegedOpcode; - return 0; - } - return readReg(miscReg); - case MISCREG_STICK: - SparcSystem *sys; - if (stickFields.npt && !isNonPriv()) { - fault = new PrivilegedAction; - return 0; - } - sys = dynamic_cast(tc->getSystemPtr()); - assert(sys != NULL); - return curTick/Clock::Int::ns - sys->sysTick | stickFields.npt << 63; case MISCREG_STICK_CMPR: - if (isNonPriv()) { - fault = new PrivilegedOpcode; - return 0; - } - return readReg(miscReg); - - - /* Hyper privileged registers */ + case MISCREG_PIL: case MISCREG_HPSTATE: case MISCREG_HINTP: - return readReg(miscReg); case MISCREG_HTSTATE: - if (tl == 0) { - fault = new IllegalInstruction; - return 0; - } - return readReg(miscReg); + case MISCREG_STRAND_STS_REG: + case MISCREG_HSTICK_CMPR: + return readReg(miscReg) ; case MISCREG_HTBA: return readReg(miscReg) & ULL(~0x7FFF); case MISCREG_HVER: return NWindows | MaxTL << 8 | MaxGL << 16; - case MISCREG_STRAND_STS_REG: - return strandStatusReg; - case MISCREG_HSTICK_CMPR: - return hstick_cmpr; default: - fault = new IllegalInstruction; - return 0; + panic("Invalid read to FS misc register\n"); } } +/* + In Niagra STICK==TICK so this isn't needed + case MISCREG_STICK: + SparcSystem *sys; + sys = dynamic_cast(tc->getSystemPtr()); + assert(sys != NULL); + return curTick/Clock::Int::ns - sys->sysTick | (stick & ~(mask(63))); +*/ + + void MiscRegFile::processTickCompare(ThreadContext *tc) @@ -221,4 +174,3 @@ MiscRegFile::processHSTickCompare(ThreadContext *tc) panic("tick compare not implemented\n"); } -}; // namespace SparcISA diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc index 2ef89c57d..71e974a36 100644 --- a/src/cpu/exetrace.cc +++ b/src/cpu/exetrace.cc @@ -279,7 +279,7 @@ Trace::InstRecord::dump(ostream &outs) // outs << endl; } -#if THE_ISA == SPARC_ISA +#if THE_ISA == SPARC_ISA && FULL_SYSTEM // Compare if (flags[LEGION_LOCKSTEP]) { @@ -338,19 +338,19 @@ Trace::InstRecord::dump(ostream &outs) for (int i = 1; i <= MaxTL; i++) { thread->setMiscReg(MISCREG_TL, i); if (thread->readMiscReg(MISCREG_TPC) != - shared_data->tpc[i]) + shared_data->tpc[i-1]) diffTpc = true; if (thread->readMiscReg(MISCREG_TNPC) != - shared_data->tnpc[i]) + shared_data->tnpc[i-1]) diffTnpc = true; if (thread->readMiscReg(MISCREG_TSTATE) != - shared_data->tstate[i]) + shared_data->tstate[i-1]) diffTstate = true; if (thread->readMiscReg(MISCREG_TT) != - shared_data->tt[i]) + shared_data->tt[i-1]) diffTt = true; if (thread->readMiscReg(MISCREG_HTSTATE) != - shared_data->htstate[i]) + shared_data->htstate[i-1]) diffHtstate = true; } thread->setMiscReg(MISCREG_TL, oldTl); @@ -527,19 +527,19 @@ Trace::InstRecord::dump(ostream &outs) thread->setMiscReg(MISCREG_TL, i); printRegPair(outs, "Tpc", thread->readMiscReg(MISCREG_TPC), - shared_data->tpc[i]); + shared_data->tpc[i-1]); printRegPair(outs, "Tnpc", thread->readMiscReg(MISCREG_TNPC), - shared_data->tnpc[i]); + shared_data->tnpc[i-1]); printRegPair(outs, "Tstate", thread->readMiscReg(MISCREG_TSTATE), - shared_data->tstate[i]); + shared_data->tstate[i-1]); printRegPair(outs, "Tt", thread->readMiscReg(MISCREG_TT), - shared_data->tt[i]); + shared_data->tt[i-1]); printRegPair(outs, "Htstate", thread->readMiscReg(MISCREG_HTSTATE), - shared_data->htstate[i]); + shared_data->htstate[i-1]); } thread->setMiscReg(MISCREG_TL, oldTl); outs << endl;