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
system.cc
tlb.cc
ua2005.cc
vtophys.cc
''')

View file

@ -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);

View file

@ -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
}

View file

@ -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<SparcSystem*>(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<SparcSystem*>(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");
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<SparcSystem*>(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<SparcSystem*>(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<SparcSystem*>(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

View file

@ -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;