diff options
-rw-r--r-- | src/arch/alpha/interrupts.hh | 5 | ||||
-rw-r--r-- | src/arch/alpha/pagetable.hh | 2 | ||||
-rw-r--r-- | src/arch/sparc/faults.cc | 40 | ||||
-rw-r--r-- | src/arch/sparc/faults.hh | 2 | ||||
-rw-r--r-- | src/arch/sparc/interrupts.hh | 134 | ||||
-rw-r--r-- | src/arch/sparc/isa_traits.hh | 9 | ||||
-rw-r--r-- | src/arch/sparc/miscregfile.cc | 4 | ||||
-rw-r--r-- | src/arch/sparc/miscregfile.hh | 30 | ||||
-rw-r--r-- | src/arch/sparc/ua2005.cc | 228 | ||||
-rw-r--r-- | src/cpu/base.cc | 6 | ||||
-rw-r--r-- | src/cpu/base.hh | 1 |
11 files changed, 286 insertions, 175 deletions
diff --git a/src/arch/alpha/interrupts.hh b/src/arch/alpha/interrupts.hh index 388ccacde..a522dec6c 100644 --- a/src/arch/alpha/interrupts.hh +++ b/src/arch/alpha/interrupts.hh @@ -52,6 +52,11 @@ namespace AlphaISA newInfoSet = false; } + void post(int int_type) + { + // sparc only + } + void post(int int_num, int index) { DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); diff --git a/src/arch/alpha/pagetable.hh b/src/arch/alpha/pagetable.hh index 7ec4a6a75..c7e1c8923 100644 --- a/src/arch/alpha/pagetable.hh +++ b/src/arch/alpha/pagetable.hh @@ -80,7 +80,7 @@ namespace AlphaISA { bool _kre() const { return (entry >> 8) & 0x1; } bool _nomb() const { return (entry >> 7) & 0x1; } int _gh() const { return (entry >> 5) & 0x3; } - bool _asm() const { return (entry >> 4) & 0x1; } + bool _asm_() const { return (entry >> 4) & 0x1; } bool _foe() const { return (entry >> 3) & 0x1; } bool _fow() const { return (entry >> 2) & 0x1; } bool _for() const { return (entry >> 1) & 0x1; } diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index af80238df..a74eebafa 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -240,7 +240,7 @@ template<> SparcFaultBase::FaultVals {"dev_mondo", 0x07D, 1611, {P, P, SH}}; template<> SparcFaultBase::FaultVals - SparcFault<ResumeableError>::vals = + SparcFault<ResumableError>::vals = {"resume_error", 0x07E, 3330, {P, P, SH}}; template<> SparcFaultBase::FaultVals @@ -436,7 +436,7 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) tc->setMiscReg(MISCREG_TT, tt); //Update the global register level - if(!gotoHpriv) + if (!gotoHpriv) tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxPGL)); else tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxGL)); @@ -448,7 +448,7 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) PSTATE |= (1 << 4); //PSTATE.am = 0 PSTATE &= ~(1 << 3); - if(!gotoHpriv) + if (!gotoHpriv) { //PSTATE.priv = 1 PSTATE |= (1 << 2); @@ -471,7 +471,7 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) //XXX Where exactly is this field? tc->setMiscReg(MISCREG_PSTATE, PSTATE); - if(gotoHpriv) + if (gotoHpriv) { //HPSTATE.red = 0 HPSTATE &= ~(1 << 5); @@ -484,16 +484,16 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) } bool changedCWP = true; - if(tt == 0x24) + if (tt == 0x24) CWP++; - else if(0x80 <= tt && tt <= 0xbf) + else if (0x80 <= tt && tt <= 0xbf) CWP += (CANSAVE + 2); - else if(0xc0 <= tt && tt <= 0xff) + else if (0xc0 <= tt && tt <= 0xff) CWP--; else changedCWP = false; - if(changedCWP) + if (changedCWP) { CWP = (CWP + NWindows) % NWindows; tc->setMiscRegWithEffect(MISCREG_CWP, CWP); @@ -534,45 +534,45 @@ void SparcFaultBase::invoke(ThreadContext * tc) //We can refer to this to see what the trap level -was-, but something //in the middle could change it in the regfile out from under us. - MiscReg TL = tc->readMiscReg(MISCREG_TL); - MiscReg TT = tc->readMiscReg(MISCREG_TT); - MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE); - MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE); + MiscReg tl = tc->readMiscReg(MISCREG_TL); + MiscReg tt = tc->readMiscReg(MISCREG_TT); + MiscReg pstate = tc->readMiscReg(MISCREG_PSTATE); + MiscReg hpstate = tc->readMiscReg(MISCREG_HPSTATE); Addr PC, NPC; PrivilegeLevel current; - if(HPSTATE & (1 << 2)) + if (hpstate & HPSTATE::hpriv) current = Hyperprivileged; - else if(PSTATE & (1 << 2)) + else if (pstate & PSTATE::priv) current = Privileged; else current = User; PrivilegeLevel level = getNextLevel(current); - if(HPSTATE & (1 << 5) || TL == MaxTL - 1) { + if ((hpstate & HPSTATE::red) || (tl == MaxTL - 1)) { getREDVector(5, PC, NPC); - doREDFault(tc, TT); + doREDFault(tc, tt); //This changes the hpstate and pstate, so we need to make sure we //save the old version on the trap stack in doREDFault. enterREDState(tc); - } else if(TL == MaxTL) { + } else if (tl == MaxTL) { panic("Should go to error state here.. crap\n"); //Do error_state somehow? //Probably inject a WDR fault using the interrupt mechanism. //What should the PC and NPC be set to? - } else if(TL > MaxPTL && level == Privileged) { + } else if (tl > MaxPTL && level == Privileged) { //guest_watchdog fault doNormalFault(tc, trapType(), true); getHyperVector(tc, PC, NPC, 2); - } else if(level == Hyperprivileged || + } else if (level == Hyperprivileged || level == Privileged && trapType() >= 384) { doNormalFault(tc, trapType(), true); getHyperVector(tc, PC, NPC, trapType()); } else { doNormalFault(tc, trapType(), false); - getPrivVector(tc, PC, NPC, trapType(), TL+1); + getPrivVector(tc, PC, NPC, trapType(), tl+1); } tc->setPC(PC); diff --git a/src/arch/sparc/faults.hh b/src/arch/sparc/faults.hh index 6b3820ddd..3c0d9674f 100644 --- a/src/arch/sparc/faults.hh +++ b/src/arch/sparc/faults.hh @@ -210,7 +210,7 @@ class CpuMondo : public SparcFault<CpuMondo> {}; class DevMondo : public SparcFault<DevMondo> {}; -class ResumeableError : public SparcFault<ResumeableError> {}; +class ResumableError : public SparcFault<ResumableError> {}; class SpillNNormal : public EnumeratedFault<SpillNNormal> { diff --git a/src/arch/sparc/interrupts.hh b/src/arch/sparc/interrupts.hh index 452164e46..99ddb4919 100644 --- a/src/arch/sparc/interrupts.hh +++ b/src/arch/sparc/interrupts.hh @@ -24,8 +24,6 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Gabe Black */ #ifndef __ARCH_SPARC_INTERRUPT_HH__ @@ -34,19 +32,45 @@ #include "arch/sparc/faults.hh" #include "cpu/thread_context.hh" - namespace SparcISA { + +enum interrupts_t { + trap_level_zero, + hstick_match, + interrupt_vector, + cpu_mondo, + dev_mondo, + resumable_error, + soft_interrupt, + num_interrupt_types +}; + class Interrupts { - protected: + private: + + bool interrupts[num_interrupt_types]; + int numPosted; public: Interrupts() { + for (int i = 0; i < num_interrupt_types; ++i) { + interrupts[i] = false; + } + numPosted = 0; + } + void post(int int_type) + { + if (int_type < 0 || int_type >= num_interrupt_types) + panic("posting unknown interrupt!\n"); + interrupts[int_type] = true; + ++numPosted; } + void post(int int_num, int index) { @@ -64,9 +88,7 @@ namespace SparcISA bool check_interrupts(ThreadContext * tc) const { - // so far only handle softint interrupts - int int_level = InterruptLevel(tc->readMiscReg(MISCREG_SOFTINT)); - if (int_level) + if (numPosted) return true; else return false; @@ -74,20 +96,96 @@ namespace SparcISA Fault getInterrupt(ThreadContext * tc) { - // 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; + int hpstate = tc->readMiscReg(MISCREG_HPSTATE); + int pstate = tc->readMiscReg(MISCREG_PSTATE); + bool ie = pstate & PSTATE::ie; + + // THESE ARE IN ORDER OF PRIORITY + // since there are early returns, and the highest + // priority interrupts should get serviced, + // it is v. important that new interrupts are inserted + // in the right order of processing + if (hpstate & HPSTATE::hpriv) { + if (ie) { + if (interrupts[hstick_match]) { + if (tc->readMiscReg(MISCREG_HINTP) & 1) { + interrupts[hstick_match] = false; + --numPosted; + return new HstickMatch; + } + } + if (interrupts[interrupt_vector]) { + interrupts[interrupt_vector] = false; + --numPosted; + //HAVEN'T IMPLed THIS YET + return NoFault; + } } else { - return new InterruptLevelN(int_level); + if (interrupts[hstick_match]) { + return NoFault; + } + + } + } else { + if (interrupts[trap_level_zero]) { + if ((pstate & HPSTATE::tlz) && (tc->readMiscReg(MISCREG_TL) == 0)) { + interrupts[trap_level_zero] = false; + --numPosted; + return new TrapLevelZero; + } + } + if (interrupts[hstick_match]) { + if (tc->readMiscReg(MISCREG_HINTP) & 1) { + interrupts[hstick_match] = false; + --numPosted; + return new HstickMatch; + } + } + if (ie) { + if (interrupts[cpu_mondo]) { + interrupts[cpu_mondo] = false; + --numPosted; + return new CpuMondo; + } + if (interrupts[dev_mondo]) { + interrupts[dev_mondo] = false; + --numPosted; + return new DevMondo; + } + if (interrupts[soft_interrupt]) { + int il = InterruptLevel(tc->readMiscReg(MISCREG_SOFTINT)); + // it seems that interrupt vectors are right in + // the middle of interrupt levels with regard to + // priority, so have to check + if ((il < 6) && + interrupts[interrupt_vector]) { + // may require more details here since there + // may be lots of interrupts embedded in an + // platform interrupt vector + interrupts[interrupt_vector] = false; + --numPosted; + //HAVEN'T IMPLed YET + return NoFault; + } else { + if (il > tc->readMiscReg(MISCREG_PIL)) { + uint64_t si = tc->readMiscReg(MISCREG_SOFTINT); + uint64_t more = si & ~(1 << (il + 1)); + if (!InterruptLevel(more)) { + interrupts[soft_interrupt] = false; + --numPosted; + } + return new InterruptLevelN(il); + } + } + } + if (interrupts[resumable_error]) { + interrupts[resumable_error] = false; + --numPosted; + return new ResumableError; + } } } + return NoFault; } void updateIntrInfo(ThreadContext * tc) diff --git a/src/arch/sparc/isa_traits.hh b/src/arch/sparc/isa_traits.hh index 3f0b9cad5..8aa8ea7f3 100644 --- a/src/arch/sparc/isa_traits.hh +++ b/src/arch/sparc/isa_traits.hh @@ -96,15 +96,6 @@ namespace SparcISA StaticInstPtr decodeInst(ExtMachInst); #if FULL_SYSTEM - ////////// Interrupt Stuff /////////// - enum InterruptLevels - { - INTLEVEL_MIN = 1, - INTLEVEL_MAX = 15, - - NumInterruptLevels = INTLEVEL_MAX - INTLEVEL_MIN - }; - // I don't know what it's for, so I don't // know what SPARC's value should be // For loading... XXX This maybe could be USegEnd?? --ali diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index 50f510289..d9fcb0280 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -214,7 +214,7 @@ MiscReg MiscRegFile::readReg(int miscReg) case MISCREG_HTSTATE: return htstate[tl-1]; case MISCREG_HINTP: - panic("HINTP not implemented\n"); + return hintp; case MISCREG_HTBA: return htba; case MISCREG_HVER: @@ -468,7 +468,7 @@ void MiscRegFile::setReg(int miscReg, const MiscReg &val) htstate[tl-1] = val; break; case MISCREG_HINTP: - panic("HINTP not implemented\n"); + hintp = val; case MISCREG_HTBA: htba = val; break; diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh index c879fd357..8a2e8e810 100644 --- a/src/arch/sparc/miscregfile.hh +++ b/src/arch/sparc/miscregfile.hh @@ -142,24 +142,26 @@ 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 + struct HPSTATE { + const static uint64_t id = 0x800; // this impl. dependent (id) field m + const static uint64_t ibe = 0x400; + const static uint64_t red = 0x20; + const static uint64_t hpriv = 0x4; + const static uint64_t tlz = 0x1; }; - enum PStateFields { - cle = 0x200, - tle = 0x100, - mm = 0xC0, - pef = 0x10, - am = 0x8, - priv = 0x4, - ie = 0x2 + + struct PSTATE { + const static int cle = 0x200; + const static int tle = 0x100; + const static int mm = 0xC0; + const static int pef = 0x10; + const static int am = 0x8; + const static int priv = 0x4; + const static int 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 f03c4da57..6220e6dec 100644 --- a/src/arch/sparc/ua2005.cc +++ b/src/arch/sparc/ua2005.cc @@ -24,8 +24,6 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Ali Saidi */ #include "arch/sparc/miscregfile.hh" @@ -38,106 +36,109 @@ using namespace SparcISA; void MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, - ThreadContext *tc) + ThreadContext *tc) { int64_t time; switch (miscReg) { /* Full system only ASRs */ - case MISCREG_SOFTINT: - // Check if we are going to interrupt because of something - setReg(miscReg, val); - tc->getCpuPtr()->checkInterrupts = true; - if (val != 0x10000 && val != 0) - warn("Writing to softint not really supported, writing: %#x\n", val); - break; - - case MISCREG_SOFTINT_CLR: - return setRegWithEffect(MISCREG_SOFTINT, ~val & softint, tc); - case MISCREG_SOFTINT_SET: - return setRegWithEffect(MISCREG_SOFTINT, val | softint, tc); - - case MISCREG_TICK_CMPR: - if (tickCompare == NULL) - tickCompare = new TickCompareEvent(this, tc); - setReg(miscReg, val); - 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)); - panic("writing to TICK compare register %#X\n", val); - break; - - case MISCREG_STICK_CMPR: - if (sTickCompare == NULL) - sTickCompare = new STickCompareEvent(this, tc); - setReg(miscReg, val); - if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled()) - sTickCompare->deschedule(); - time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) - - tc->getCpuPtr()->instCount(); - if (!(stick_cmpr & ~mask(63)) && time > 0) - sTickCompare->schedule(time * tc->getCpuPtr()->cycles(1) + curTick); - DPRINTF(Timer, "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); - - case MISCREG_PIL: - if (val < pil) { - tc->getCpuPtr()->checkInterrupts = true; - } - setReg(miscReg, val); - 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)); - 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_HSTICK_CMPR: - if (hSTickCompare == NULL) - hSTickCompare = new HSTickCompareEvent(this, tc); - setReg(miscReg, val); - if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled()) - hSTickCompare->deschedule(); - time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) - - tc->getCpuPtr()->instCount(); - if (!(hstick_cmpr & ~mask(63)) && time > 0) - hSTickCompare->schedule(curTick + time * tc->getCpuPtr()->cycles(1)); - DPRINTF(Timer, "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: - panic("Invalid write to FS misc register %s\n", getMiscRegName(miscReg)); + case MISCREG_SOFTINT: + setReg(miscReg, val);; + if (val != 0x10000 && val != 0) + warn("Writing to softint not really supported, writing: %#x\n", val); + break; + + case MISCREG_SOFTINT_CLR: + return setRegWithEffect(MISCREG_SOFTINT, ~val & softint, tc); + case MISCREG_SOFTINT_SET: + tc->getCpuPtr()->checkInterrupts = true; + tc->getCpuPtr()->post_interrupt(soft_interrupt); + return setRegWithEffect(MISCREG_SOFTINT, val | softint, tc); + + case MISCREG_TICK_CMPR: + if (tickCompare == NULL) + tickCompare = new TickCompareEvent(this, tc); + setReg(miscReg, val); + 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)); + panic("writing to TICK compare register %#X\n", val); + break; + + case MISCREG_STICK_CMPR: + if (sTickCompare == NULL) + sTickCompare = new STickCompareEvent(this, tc); + setReg(miscReg, val); + if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled()) + sTickCompare->deschedule(); + time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) - + tc->getCpuPtr()->instCount(); + if (!(stick_cmpr & ~mask(63)) && time > 0) + sTickCompare->schedule(time * tc->getCpuPtr()->cycles(1) + curTick); + DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val); + break; + + case MISCREG_PSTATE: + if (val & PSTATE::ie && !(pstate & PSTATE::ie)) { + tc->getCpuPtr()->checkInterrupts = true; + } + setReg(miscReg, val); + + case MISCREG_PIL: + if (val < pil) { + tc->getCpuPtr()->checkInterrupts = true; + } + setReg(miscReg, val); + break; + + case MISCREG_HVER: + panic("Shouldn't be writing HVER\n"); + + case MISCREG_HINTP: + setReg(miscReg, val); + + case MISCREG_HTBA: + // clear lower 7 bits on writes. + setReg(miscReg, val & ULL(~0x7FFF)); + 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_HSTICK_CMPR: + if (hSTickCompare == NULL) + hSTickCompare = new HSTickCompareEvent(this, tc); + setReg(miscReg, val); + if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled()) + hSTickCompare->deschedule(); + time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) - + tc->getCpuPtr()->instCount(); + if (!(hstick_cmpr & ~mask(63)) && time > 0) + hSTickCompare->schedule(curTick + time * tc->getCpuPtr()->cycles(1)); + DPRINTF(Timer, "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 | HPSTATE::id); + break; + case MISCREG_HTSTATE: + case MISCREG_STRAND_STS_REG: + setReg(miscReg, val); + break; + + default: + panic("Invalid write to FS misc register %s\n", getMiscRegName(miscReg)); } } @@ -145,7 +146,7 @@ MiscReg MiscRegFile::readFSRegWithEffect(int miscReg, ThreadContext * tc) { switch (miscReg) { - /* Privileged registers. */ + /* Privileged registers. */ case MISCREG_QUEUE_CPU_MONDO_HEAD: case MISCREG_QUEUE_CPU_MONDO_TAIL: case MISCREG_QUEUE_DEV_MONDO_HEAD: @@ -175,12 +176,12 @@ MiscRegFile::readFSRegWithEffect(int miscReg, ThreadContext * tc) } } /* - 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))); + 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))); */ @@ -199,14 +200,17 @@ MiscRegFile::processSTickCompare(ThreadContext *tc) // more int ticks; ticks = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) - - tc->getCpuPtr()->instCount(); + tc->getCpuPtr()->instCount(); assert(ticks >= 0 && "stick compare missed interrupt cycle"); if (ticks == 0) { DPRINTF(Timer, "STick compare cycle reached at %#x\n", (stick_cmpr & mask(63))); - tc->getCpuPtr()->checkInterrupts = true; - softint |= ULL(1) << 16; + if (!(tc->readMiscReg(MISCREG_STICK_CMPR) & (ULL(1) << 63))) { + tc->getCpuPtr()->post_interrupt(soft_interrupt); + tc->getCpuPtr()->checkInterrupts = true; + setRegWithEffect(MISCREG_SOFTINT, softint | (ULL(1) << 16), tc); + } } else sTickCompare->schedule(ticks * tc->getCpuPtr()->cycles(1) + curTick); } @@ -219,13 +223,17 @@ MiscRegFile::processHSTickCompare(ThreadContext *tc) // more int ticks; ticks = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) - - tc->getCpuPtr()->instCount(); + tc->getCpuPtr()->instCount(); assert(ticks >= 0 && "hstick compare missed interrupt cycle"); if (ticks == 0) { DPRINTF(Timer, "HSTick compare cycle reached at %#x\n", (stick_cmpr & mask(63))); - tc->getCpuPtr()->checkInterrupts = true; + if (!(tc->readMiscReg(MISCREG_HSTICK_CMPR) & (ULL(1) << 63))) { + setRegWithEffect(MISCREG_HINTP, 1, tc); + tc->getCpuPtr()->post_interrupt(hstick_match); + tc->getCpuPtr()->checkInterrupts = true; + } // Need to do something to cause interrupt to happen here !!! @todo } else sTickCompare->schedule(ticks * tc->getCpuPtr()->cycles(1) + curTick); diff --git a/src/cpu/base.cc b/src/cpu/base.cc index 31604ad58..b03bc19a5 100644 --- a/src/cpu/base.cc +++ b/src/cpu/base.cc @@ -363,6 +363,12 @@ BaseCPU::ProfileEvent::process() } void +BaseCPU::post_interrupt(int int_type) +{ + interrupts.post(int_type); +} + +void BaseCPU::post_interrupt(int int_num, int index) { checkInterrupts = true; diff --git a/src/cpu/base.hh b/src/cpu/base.hh index 8c6b079da..89c7d9dda 100644 --- a/src/cpu/base.hh +++ b/src/cpu/base.hh @@ -102,6 +102,7 @@ class BaseCPU : public MemObject TheISA::Interrupts interrupts; public: + virtual void post_interrupt(int int_type); virtual void post_interrupt(int int_num, int index); virtual void clear_interrupt(int int_num, int index); virtual void clear_interrupts(); |