Merge zizzer:/bk/sparcfs

into  zed.eecs.umich.edu:/z/hsul/work/sparc/m5

--HG--
extra : convert_revision : 3186d6055794b41c26eb8d2411903869b5b39329
This commit is contained in:
Lisa Hsu 2006-12-04 19:39:58 -05:00
commit 2de685cc21
5 changed files with 89 additions and 123 deletions

View file

@ -60,6 +60,7 @@ full_system_sources = Split('''
stacktrace.cc stacktrace.cc
system.cc system.cc
tlb.cc tlb.cc
ua2005.cc
vtophys.cc vtophys.cc
''') ''')

View file

@ -213,6 +213,10 @@ namespace SparcISA
// These need to check the int_dis field and if 0 then // These need to check the int_dis field and if 0 then
// set appropriate bit in softint and checkinterrutps on the cpu // set appropriate bit in softint and checkinterrutps on the cpu
#if FULL_SYSTEM #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 /** Process a tick compare event and generate an interrupt on the cpu if
* appropriate. */ * appropriate. */
void processTickCompare(ThreadContext *tc); void processTickCompare(ThreadContext *tc);

View file

@ -37,6 +37,7 @@
* ISA-specific helper functions for memory mapped IPR accesses. * ISA-specific helper functions for memory mapped IPR accesses.
*/ */
#include "config/full_system.hh"
#include "cpu/thread_context.hh" #include "cpu/thread_context.hh"
#include "mem/packet.hh" #include "mem/packet.hh"
#include "arch/sparc/tlb.hh" #include "arch/sparc/tlb.hh"
@ -47,14 +48,22 @@ namespace SparcISA
inline Tick inline Tick
handleIprRead(ThreadContext *xc, Packet *pkt) handleIprRead(ThreadContext *xc, Packet *pkt)
{ {
#if FULL_SYSTEM
return xc->getDTBPtr()->doMmuRegRead(xc, pkt); return xc->getDTBPtr()->doMmuRegRead(xc, pkt);
#else
panic("Shouldn't have a memory mapped register in SE\n");
#endif
} }
inline Tick inline Tick
handleIprWrite(ThreadContext *xc, Packet *pkt) handleIprWrite(ThreadContext *xc, Packet *pkt)
{ {
#if FULL_SYSTEM
return xc->getDTBPtr()->doMmuRegWrite(xc, pkt); return xc->getDTBPtr()->doMmuRegWrite(xc, pkt);
#else
panic("Shouldn't have a memory mapped register in SE\n");
#endif
} }

View file

@ -28,27 +28,32 @@
* Authors: Ali Saidi * 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 using namespace SparcISA;
SparcISA::MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
void
MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
ThreadContext *tc) ThreadContext *tc)
{ {
int64_t time; int64_t time;
SparcSystem *sys; int oldLevel, newLevel;
switch (miscReg) { switch (miscReg) {
/* Full system only ASRs */ /* Full system only ASRs */
case MISCREG_SOFTINT: case MISCREG_SOFTINT:
if (isNonPriv())
return new PrivilegedOpcode;
// Check if we are going to interrupt because of something // Check if we are going to interrupt because of something
int oldLevel = InterruptLevel(softint); oldLevel = InterruptLevel(softint);
int newLevel = InterruptLevel(val); newLevel = InterruptLevel(val);
setReg(miscReg, val); setReg(miscReg, val);
if (newLevel > oldLevel) if (newLevel > oldLevel)
; // MUST DO SOMETHING HERE TO TELL CPU TO LOOK FOR INTERRUPTS XXX ; // MUST DO SOMETHING HERE TO TELL CPU TO LOOK FOR INTERRUPTS XXX
//tc->getCpuPtr()->checkInterrupts = true; //tc->getCpuPtr()->checkInterrupts = true;
return NoFault; panic("SOFTINT not implemented\n");
break;
case MISCREG_SOFTINT_CLR: case MISCREG_SOFTINT_CLR:
return setRegWithEffect(miscReg, ~val & softint, tc); return setRegWithEffect(miscReg, ~val & softint, tc);
@ -56,152 +61,100 @@ SparcISA::MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
return setRegWithEffect(miscReg, val | softint, tc); return setRegWithEffect(miscReg, val | softint, tc);
case MISCREG_TICK_CMPR: case MISCREG_TICK_CMPR:
if (isNonPriv())
return new PrivilegedOpcode;
if (tickCompare == NULL) if (tickCompare == NULL)
tickCompare = new TickCompareEvent(this, tc); tickCompare = new TickCompareEvent(this, tc);
setReg(miscReg, val); setReg(miscReg, val);
if (tick_cmprFields.int_dis && tickCompare.scheduled()) if ((tick_cmpr & mask(63)) && tickCompare->scheduled())
tickCompare.deschedule(); tickCompare->deschedule();
time = tick_cmprFields.tick_cmpr - tickFields.counter; time = (tick_cmpr & mask(63)) - (tick & mask(63));
if (!tick_cmprFields.int_dis && time > 0) if (!(tick_cmpr & ~mask(63)) && time > 0)
tickCompare.schedule(time * tc->getCpuPtr()->cycles(1)); tickCompare->schedule(time * tc->getCpuPtr()->cycles(1));
return NoFault; break;
case MISCREG_STICK:
if (isNonPriv())
return new PrivilegedOpcode;
if (isPriv())
return new PrivilegedAction;
sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
assert(sys != NULL);
sys->sysTick = curTick/Clock::Int::ns - val & ~Bit64;
stickFields.npt = val & Bit64 ? 1 : 0;
return NoFault;
case MISCREG_STICK_CMPR: case MISCREG_STICK_CMPR:
if (isNonPriv())
return new PrivilegedOpcode;
if (sTickCompare == NULL) if (sTickCompare == NULL)
sTickCompare = new STickCompareEvent(this, tc); sTickCompare = new STickCompareEvent(this, tc);
sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
assert(sys != NULL);
setReg(miscReg, val); setReg(miscReg, val);
if (stick_cmprFields.int_dis && sTickCompare.scheduled()) if ((stick_cmpr & mask(63)) && sTickCompare->scheduled())
sTickCompare.deschedule(); sTickCompare->deschedule();
time = stick_cmprFields.tick_cmpr - sys->sysTick; time = (stick_cmpr & mask(63)) - (stick & mask(63));
if (!stick_cmprFields.int_dis && time > 0) if (!(stick_cmpr & ~mask(63)) && time > 0)
sTickCompare.schedule(time * Clock::Int::ns); sTickCompare->schedule(time * tc->getCpuPtr()->cycles(1));
return NoFault; break;
/* Fullsystem only Priv registers. */
case MISCREG_PIL: case MISCREG_PIL:
if (FULL_SYSTEM) { setReg(miscReg, val);
setReg(miscReg, val); //tc->getCpuPtr()->checkInterrupts;
//tc->getCpuPtr()->checkInterrupts; // MUST DO SOMETHING HERE TO TELL CPU TO LOOK FOR INTERRUPTS XXX
// MUST DO SOMETHING HERE TO TELL CPU TO LOOK FOR INTERRUPTS XXX panic("PIL not implemented\n");
return NoFault; break;
} else
panic("PIL not implemented for syscall emulation\n");
/* Hyper privileged registers */ case MISCREG_HVER:
case MISCREG_HPSTATE: panic("Shouldn't be writing HVER\n");
case MISCREG_HINTP:
setReg(miscReg, val);
return NoFault;
case MISCREG_HTSTATE:
if (tl == 0)
return new IllegalInstruction;
setReg(miscReg, val);
return NoFault;
case MISCREG_HTBA: case MISCREG_HTBA:
// clear lower 7 bits on writes. // clear lower 7 bits on writes.
setReg(miscReg, val & ULL(~0x7FFF)); setReg(miscReg, val & ULL(~0x7FFF));
return NoFault; break;
case MISCREG_STRAND_STS_REG:
setReg(miscReg, strandStatusReg);
return NoFault;
case MISCREG_HSTICK_CMPR: case MISCREG_HSTICK_CMPR:
if (isNonPriv())
return new PrivilegedOpcode;
if (hSTickCompare == NULL) if (hSTickCompare == NULL)
hSTickCompare = new HSTickCompareEvent(this, tc); hSTickCompare = new HSTickCompareEvent(this, tc);
sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
assert(sys != NULL);
setReg(miscReg, val); setReg(miscReg, val);
if (hstick_cmprFields.int_dis && hSTickCompare.scheduled()) if ((hstick_cmpr & mask(63)) && hSTickCompare->scheduled())
hSTickCompare.deschedule(); hSTickCompare->deschedule();
int64_t time = hstick_cmprFields.tick_cmpr - sys->sysTick; time = (hstick_cmpr & mask(63)) - (stick & mask(63));
if (!hstick_cmprFields.int_dis && time > 0) if (!(hstick_cmpr & ~mask(63)) && time > 0)
hSTickCompare.schedule(time * Clock::Int::ns); hSTickCompare->schedule(time * tc->getCpuPtr()->cycles(1));
return NoFault; break;
case MISCREG_HPSTATE:
case MISCREG_HTSTATE:
case MISCREG_STRAND_STS_REG:
setReg(miscReg, val);
break;
default: default:
return new IllegalInstruction; panic("Invalid write to FS misc register\n");
} }
} }
MiscReg MiscReg
MiscRegFile::readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext * tc) MiscRegFile::readFSRegWithEffect(int miscReg, ThreadContext * tc)
{ {
switch (miscReg) { switch (miscReg) {
/* Privileged registers. */ /* Privileged registers. */
case MISCREG_SOFTINT: case MISCREG_SOFTINT:
if (isNonPriv()) {
fault = new PrivilegedOpcode;
return 0;
}
return readReg(miscReg);
case MISCREG_TICK_CMPR: 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<SparcSystem*>(tc->getSystemPtr());
assert(sys != NULL);
return curTick/Clock::Int::ns - sys->sysTick | stickFields.npt << 63;
case MISCREG_STICK_CMPR: case MISCREG_STICK_CMPR:
if (isNonPriv()) { case MISCREG_PIL:
fault = new PrivilegedOpcode;
return 0;
}
return readReg(miscReg);
/* Hyper privileged registers */
case MISCREG_HPSTATE: case MISCREG_HPSTATE:
case MISCREG_HINTP: case MISCREG_HINTP:
return readReg(miscReg);
case MISCREG_HTSTATE: case MISCREG_HTSTATE:
if (tl == 0) { case MISCREG_STRAND_STS_REG:
fault = new IllegalInstruction; case MISCREG_HSTICK_CMPR:
return 0; return readReg(miscReg) ;
}
return readReg(miscReg);
case MISCREG_HTBA: case MISCREG_HTBA:
return readReg(miscReg) & ULL(~0x7FFF); return readReg(miscReg) & ULL(~0x7FFF);
case MISCREG_HVER: case MISCREG_HVER:
return NWindows | MaxTL << 8 | MaxGL << 16; return NWindows | MaxTL << 8 | MaxGL << 16;
case MISCREG_STRAND_STS_REG:
return strandStatusReg;
case MISCREG_HSTICK_CMPR:
return hstick_cmpr;
default: default:
fault = new IllegalInstruction; panic("Invalid read to FS misc register\n");
return 0;
} }
} }
/*
In Niagra STICK==TICK so this isn't needed
case MISCREG_STICK:
SparcSystem *sys;
sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
assert(sys != NULL);
return curTick/Clock::Int::ns - sys->sysTick | (stick & ~(mask(63)));
*/
void void
MiscRegFile::processTickCompare(ThreadContext *tc) MiscRegFile::processTickCompare(ThreadContext *tc)
@ -221,4 +174,3 @@ MiscRegFile::processHSTickCompare(ThreadContext *tc)
panic("tick compare not implemented\n"); panic("tick compare not implemented\n");
} }
}; // namespace SparcISA

View file

@ -279,7 +279,7 @@ Trace::InstRecord::dump(ostream &outs)
// //
outs << endl; outs << endl;
} }
#if THE_ISA == SPARC_ISA #if THE_ISA == SPARC_ISA && FULL_SYSTEM
// Compare // Compare
if (flags[LEGION_LOCKSTEP]) if (flags[LEGION_LOCKSTEP])
{ {
@ -338,19 +338,19 @@ Trace::InstRecord::dump(ostream &outs)
for (int i = 1; i <= MaxTL; i++) { for (int i = 1; i <= MaxTL; i++) {
thread->setMiscReg(MISCREG_TL, i); thread->setMiscReg(MISCREG_TL, i);
if (thread->readMiscReg(MISCREG_TPC) != if (thread->readMiscReg(MISCREG_TPC) !=
shared_data->tpc[i]) shared_data->tpc[i-1])
diffTpc = true; diffTpc = true;
if (thread->readMiscReg(MISCREG_TNPC) != if (thread->readMiscReg(MISCREG_TNPC) !=
shared_data->tnpc[i]) shared_data->tnpc[i-1])
diffTnpc = true; diffTnpc = true;
if (thread->readMiscReg(MISCREG_TSTATE) != if (thread->readMiscReg(MISCREG_TSTATE) !=
shared_data->tstate[i]) shared_data->tstate[i-1])
diffTstate = true; diffTstate = true;
if (thread->readMiscReg(MISCREG_TT) != if (thread->readMiscReg(MISCREG_TT) !=
shared_data->tt[i]) shared_data->tt[i-1])
diffTt = true; diffTt = true;
if (thread->readMiscReg(MISCREG_HTSTATE) != if (thread->readMiscReg(MISCREG_HTSTATE) !=
shared_data->htstate[i]) shared_data->htstate[i-1])
diffHtstate = true; diffHtstate = true;
} }
thread->setMiscReg(MISCREG_TL, oldTl); thread->setMiscReg(MISCREG_TL, oldTl);
@ -527,19 +527,19 @@ Trace::InstRecord::dump(ostream &outs)
thread->setMiscReg(MISCREG_TL, i); thread->setMiscReg(MISCREG_TL, i);
printRegPair(outs, "Tpc", printRegPair(outs, "Tpc",
thread->readMiscReg(MISCREG_TPC), thread->readMiscReg(MISCREG_TPC),
shared_data->tpc[i]); shared_data->tpc[i-1]);
printRegPair(outs, "Tnpc", printRegPair(outs, "Tnpc",
thread->readMiscReg(MISCREG_TNPC), thread->readMiscReg(MISCREG_TNPC),
shared_data->tnpc[i]); shared_data->tnpc[i-1]);
printRegPair(outs, "Tstate", printRegPair(outs, "Tstate",
thread->readMiscReg(MISCREG_TSTATE), thread->readMiscReg(MISCREG_TSTATE),
shared_data->tstate[i]); shared_data->tstate[i-1]);
printRegPair(outs, "Tt", printRegPair(outs, "Tt",
thread->readMiscReg(MISCREG_TT), thread->readMiscReg(MISCREG_TT),
shared_data->tt[i]); shared_data->tt[i-1]);
printRegPair(outs, "Htstate", printRegPair(outs, "Htstate",
thread->readMiscReg(MISCREG_HTSTATE), thread->readMiscReg(MISCREG_HTSTATE),
shared_data->htstate[i]); shared_data->htstate[i-1]);
} }
thread->setMiscReg(MISCREG_TL, oldTl); thread->setMiscReg(MISCREG_TL, oldTl);
outs << endl; outs << endl;