diff options
Diffstat (limited to 'src/arch/sparc/ua2005.cc')
-rw-r--r-- | src/arch/sparc/ua2005.cc | 232 |
1 files changed, 105 insertions, 127 deletions
diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc index 6493ddfd5..0db5f6acc 100644 --- a/src/arch/sparc/ua2005.cc +++ b/src/arch/sparc/ua2005.cc @@ -28,27 +28,27 @@ * 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; 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); setReg(miscReg, val); - if (newLevel > oldLevel) - ; // MUST DO SOMETHING HERE TO TELL CPU TO LOOK FOR INTERRUPTS XXX - //tc->getCpuPtr()->checkInterrupts = true; - return NoFault; + tc->getCpuPtr()->checkInterrupts = true; + warn("Writing to softint not really supported, writing: %#x\n", val); + break; case MISCREG_SOFTINT_CLR: return setRegWithEffect(miscReg, ~val & softint, tc); @@ -56,152 +56,131 @@ 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)); + warn ("writing to TICK compare register %#X\n", val); + 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; - - /* 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"); - - /* Hyper privileged registers */ - case MISCREG_HPSTATE: - case MISCREG_HINTP: + 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)); + warn ("writing to sTICK compare register value %#X\n", val); + break; + + case MISCREG_PSTATE: + if (val & ie && !(pstate & ie)) { + tc->getCpuPtr()->checkInterrupts = true; + } setReg(miscReg, val); - return NoFault; - case MISCREG_HTSTATE: - if (tl == 0) - return new IllegalInstruction; + + case MISCREG_PIL: + if (val < pil) { + tc->getCpuPtr()->checkInterrupts = true; + } setReg(miscReg, val); - return NoFault; + break; + + 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_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: + setReg(miscReg, val); + tc->getCpuPtr()->checkInterrupts = true; + 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)); + warn ("writing to hsTICK compare register value %#X\n", val); + break; + + case MISCREG_HPSTATE: + // T1000 spec says impl. dependent val must always be 1 + setReg(miscReg, val | id); + break; + case MISCREG_HTSTATE: + case MISCREG_STRAND_STS_REG: + setReg(miscReg, val); + break; + default: - return new IllegalInstruction; + panic("Invalid write to FS misc register %s\n", getMiscRegName(miscReg)); } } 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); + /* Privileged registers. */ + 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: + case MISCREG_SOFTINT: + case MISCREG_TICK_CMPR: + case MISCREG_STICK_CMPR: + case MISCREG_PIL: + case MISCREG_HPSTATE: + case MISCREG_HINTP: + case MISCREG_HTSTATE: + 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; + + default: + panic("Invalid read to FS misc register\n"); + } +} +/* + In Niagra STICK==TICK so this isn't needed 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); + return curTick/Clock::Int::ns - sys->sysTick | (stick & ~(mask(63))); +*/ - /* Hyper privileged registers */ - 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_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; - } -} void MiscRegFile::processTickCompare(ThreadContext *tc) @@ -221,4 +200,3 @@ MiscRegFile::processHSTickCompare(ThreadContext *tc) panic("tick compare not implemented\n"); } -}; // namespace SparcISA |