diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/sparc/interrupts.hh | 41 | ||||
-rw-r--r-- | src/arch/sparc/miscregfile.cc | 2 | ||||
-rw-r--r-- | src/arch/sparc/miscregfile.hh | 18 | ||||
-rw-r--r-- | src/arch/sparc/ua2005.cc | 25 |
4 files changed, 59 insertions, 27 deletions
diff --git a/src/arch/sparc/interrupts.hh b/src/arch/sparc/interrupts.hh index 70838d1ce..452164e46 100644 --- a/src/arch/sparc/interrupts.hh +++ b/src/arch/sparc/interrupts.hh @@ -32,51 +32,62 @@ #define __ARCH_SPARC_INTERRUPT_HH__ #include "arch/sparc/faults.hh" +#include "cpu/thread_context.hh" + namespace SparcISA { class Interrupts { protected: - Fault interrupts[NumInterruptLevels]; - bool requested[NumInterruptLevels]; + public: Interrupts() { - for(int x = 0; x < NumInterruptLevels; x++) - { - interrupts[x] = new InterruptLevelN(x); - requested[x] = false; - } + } void post(int int_num, int index) { - if(int_num < 0 || int_num >= NumInterruptLevels) - panic("int_num out of bounds\n"); - requested[int_num] = true; } void clear(int int_num, int index) { - requested[int_num] = false; + } void clear_all() { - for(int x = 0; x < NumInterruptLevels; x++) - requested[x] = false; + } bool check_interrupts(ThreadContext * tc) const { - return true; + // so far only handle softint interrupts + int int_level = InterruptLevel(tc->readMiscReg(MISCREG_SOFTINT)); + if (int_level) + return true; + else + return false; } Fault getInterrupt(ThreadContext * tc) { - return NoFault; + // conditioning the softint interrups + if (tc->readMiscReg(MISCREG_HPSTATE) & hpriv) { + // if running in privileged mode, then pend the interrupt + return NoFault; + } else { + int int_level = InterruptLevel(tc->readMiscReg(MISCREG_SOFTINT)); + if ((int_level <= tc->readMiscReg(MISCREG_PIL)) || + !(tc->readMiscReg(MISCREG_PSTATE) & ie)) { + // if PIL or no interrupt enabled, then pend the interrupt + return NoFault; + } else { + return new InterruptLevelN(int_level); + } + } } void updateIntrInfo(ThreadContext * tc) diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index 47b4771d9..0094f2353 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -369,7 +369,7 @@ void MiscRegFile::setReg(int miscReg, const MiscReg &val) gsr = val; break; case MISCREG_SOFTINT: - softint = val; + softint |= val; break; case MISCREG_TICK_CMPR: tick_cmpr = val; diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh index 3b8a977cc..d09005795 100644 --- a/src/arch/sparc/miscregfile.hh +++ b/src/arch/sparc/miscregfile.hh @@ -140,6 +140,24 @@ namespace SparcISA MISCREG_NUMMISCREGS }; + enum HPStateFields { + id = 0x800, // this impl. dependent (id) field must always be '1' for T1000 + ibe = 0x400, + red = 0x20, + hpriv = 0x4, + tlz = 0x1 + }; + + enum PStateFields { + cle = 0x200, + tle = 0x100, + mm = 0xC0, + pef = 0x10, + am = 0x8, + priv = 0x4, + ie = 0x2 + }; + const int NumMiscArchRegs = MISCREG_NUMMISCREGS; const int NumMiscRegs = MISCREG_NUMMISCREGS; diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc index 32bc2a44b..c5188f405 100644 --- a/src/arch/sparc/ua2005.cc +++ b/src/arch/sparc/ua2005.cc @@ -41,18 +41,12 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, ThreadContext *tc) { int64_t time; - int oldLevel, newLevel; switch (miscReg) { /* Full system only ASRs */ case MISCREG_SOFTINT: // Check if we are going to interrupt because of something - 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; - panic("SOFTINT not implemented\n"); + tc->getCpuPtr()->checkInterrupts = true; break; case MISCREG_SOFTINT_CLR: @@ -82,11 +76,17 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, sTickCompare->schedule(time * tc->getCpuPtr()->cycles(1)); break; + case MISCREG_PSTATE: + if (val & ie && !(pstate & ie)) { + tc->getCpuPtr()->checkInterrupts = true; + } + setReg(miscReg, val); + case MISCREG_PIL: + if (val < pil) { + tc->getCpuPtr()->checkInterrupts = true; + } setReg(miscReg, val); - //tc->getCpuPtr()->checkInterrupts; - // MUST DO SOMETHING HERE TO TELL CPU TO LOOK FOR INTERRUPTS XXX - panic("PIL not implemented\n"); break; case MISCREG_HVER: @@ -109,13 +109,16 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, break; case MISCREG_HPSTATE: + // T1000 spec says impl. dependent val must always be 1 + setReg(miscReg, val | id); + case MISCREG_HTSTATE: case MISCREG_STRAND_STS_REG: setReg(miscReg, val); break; default: - panic("Invalid write to FS misc register\n"); + panic("Invalid write to FS misc register %s\n", getMiscRegName(miscReg)); } } |