diff options
Diffstat (limited to 'src/arch/alpha/interrupts.hh')
-rw-r--r-- | src/arch/alpha/interrupts.hh | 239 |
1 files changed, 130 insertions, 109 deletions
diff --git a/src/arch/alpha/interrupts.hh b/src/arch/alpha/interrupts.hh index 6453edf97..f8e0ad4ef 100644 --- a/src/arch/alpha/interrupts.hh +++ b/src/arch/alpha/interrupts.hh @@ -35,142 +35,163 @@ #include "arch/alpha/faults.hh" #include "arch/alpha/isa_traits.hh" #include "base/compiler.hh" +#include "base/trace.hh" #include "cpu/thread_context.hh" +#include "params/AlphaInterrupts.hh" +#include "sim/sim_object.hh" -namespace AlphaISA +namespace AlphaISA { + +class Interrupts : public SimObject { - class Interrupts + private: + bool newInfoSet; + int newIpl; + int newSummary; + BaseCPU * cpu; + + protected: + uint64_t interrupts[NumInterruptLevels]; + uint64_t intstatus; + + public: + typedef AlphaInterruptsParams Params; + + const Params * + params() const { - protected: - uint64_t interrupts[NumInterruptLevels]; - uint64_t intstatus; - - public: - Interrupts() - { - memset(interrupts, 0, sizeof(interrupts)); - intstatus = 0; - newInfoSet = false; - } + return dynamic_cast<const Params *>(_params); + } - void post(int int_num, int index) - { - DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); + Interrupts(Params * p) : SimObject(p), cpu(NULL) + { + memset(interrupts, 0, sizeof(interrupts)); + intstatus = 0; + newInfoSet = false; + } - if (int_num < 0 || int_num >= NumInterruptLevels) - panic("int_num out of bounds\n"); + void + setCPU(BaseCPU * _cpu) + { + cpu = _cpu; + } - if (index < 0 || index >= sizeof(uint64_t) * 8) - panic("int_num out of bounds\n"); + void + post(int int_num, int index) + { + DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); - interrupts[int_num] |= 1 << index; - intstatus |= (ULL(1) << int_num); - } + if (int_num < 0 || int_num >= NumInterruptLevels) + panic("int_num out of bounds\n"); - void clear(int int_num, int index) - { - DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); + if (index < 0 || index >= (int)sizeof(uint64_t) * 8) + panic("int_num out of bounds\n"); - if (int_num < 0 || int_num >= TheISA::NumInterruptLevels) - panic("int_num out of bounds\n"); + interrupts[int_num] |= 1 << index; + intstatus |= (ULL(1) << int_num); + } - if (index < 0 || index >= sizeof(uint64_t) * 8) - panic("int_num out of bounds\n"); + void + clear(int int_num, int index) + { + DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); - interrupts[int_num] &= ~(1 << index); - if (interrupts[int_num] == 0) - intstatus &= ~(ULL(1) << int_num); - } + if (int_num < 0 || int_num >= NumInterruptLevels) + panic("int_num out of bounds\n"); - void clear_all() - { - DPRINTF(Interrupt, "Interrupts all cleared\n"); + if (index < 0 || index >= (int)sizeof(uint64_t) * 8) + panic("int_num out of bounds\n"); - memset(interrupts, 0, sizeof(interrupts)); - intstatus = 0; - } + interrupts[int_num] &= ~(1 << index); + if (interrupts[int_num] == 0) + intstatus &= ~(ULL(1) << int_num); + } - void serialize(std::ostream &os) - { - SERIALIZE_ARRAY(interrupts, NumInterruptLevels); - SERIALIZE_SCALAR(intstatus); - } + void + clearAll() + { + DPRINTF(Interrupt, "Interrupts all cleared\n"); - void unserialize(Checkpoint *cp, const std::string §ion) - { - UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels); - UNSERIALIZE_SCALAR(intstatus); - } + memset(interrupts, 0, sizeof(interrupts)); + intstatus = 0; + } - bool check_interrupts(ThreadContext * tc) const - { - return (intstatus != 0) && !(tc->readPC() & 0x3); - } + void + serialize(std::ostream &os) + { + SERIALIZE_ARRAY(interrupts, NumInterruptLevels); + SERIALIZE_SCALAR(intstatus); + } - Fault getInterrupt(ThreadContext * tc) - { - int ipl = 0; - int summary = 0; - - if (tc->readMiscRegNoEffect(IPR_ASTRR)) - panic("asynchronous traps not implemented\n"); - - if (tc->readMiscRegNoEffect(IPR_SIRR)) { - for (int i = INTLEVEL_SOFTWARE_MIN; - i < INTLEVEL_SOFTWARE_MAX; i++) { - if (tc->readMiscRegNoEffect(IPR_SIRR) & (ULL(1) << i)) { - // See table 4-19 of 21164 hardware reference - ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; - summary |= (ULL(1) << i); - } - } - } + void + unserialize(Checkpoint *cp, const std::string §ion) + { + UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels); + UNSERIALIZE_SCALAR(intstatus); + } + + bool + checkInterrupts(ThreadContext *tc) const + { + return (intstatus != 0) && !(tc->readPC() & 0x3); + } - uint64_t interrupts = intstatus; - if (interrupts) { - for (int i = INTLEVEL_EXTERNAL_MIN; - i < INTLEVEL_EXTERNAL_MAX; i++) { - if (interrupts & (ULL(1) << i)) { - // See table 4-19 of 21164 hardware reference - ipl = i; - summary |= (ULL(1) << i); - } + Fault + getInterrupt(ThreadContext *tc) + { + int ipl = 0; + int summary = 0; + + if (tc->readMiscRegNoEffect(IPR_ASTRR)) + panic("asynchronous traps not implemented\n"); + + if (tc->readMiscRegNoEffect(IPR_SIRR)) { + for (int i = INTLEVEL_SOFTWARE_MIN; + i < INTLEVEL_SOFTWARE_MAX; i++) { + if (tc->readMiscRegNoEffect(IPR_SIRR) & (ULL(1) << i)) { + // See table 4-19 of 21164 hardware reference + ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; + summary |= (ULL(1) << i); } } + } - if (ipl && ipl > tc->readMiscRegNoEffect(IPR_IPLR)) { - newIpl = ipl; - newSummary = summary; - newInfoSet = true; - DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", - tc->readMiscRegNoEffect(IPR_IPLR), ipl, summary); - - return new InterruptFault; - } else { - return NoFault; + uint64_t interrupts = intstatus; + if (interrupts) { + for (int i = INTLEVEL_EXTERNAL_MIN; + i < INTLEVEL_EXTERNAL_MAX; i++) { + if (interrupts & (ULL(1) << i)) { + // See table 4-19 of 21164 hardware reference + ipl = i; + summary |= (ULL(1) << i); + } } } - void updateIntrInfo(ThreadContext *tc) - { - assert(newInfoSet); - tc->setMiscRegNoEffect(IPR_ISR, newSummary); - tc->setMiscRegNoEffect(IPR_INTID, newIpl); - newInfoSet = false; - } + if (ipl && ipl > tc->readMiscRegNoEffect(IPR_IPLR)) { + newIpl = ipl; + newSummary = summary; + newInfoSet = true; + DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", + tc->readMiscRegNoEffect(IPR_IPLR), ipl, summary); - uint64_t get_vec(int int_num) - { - panic("Shouldn't be called for Alpha\n"); - M5_DUMMY_RETURN + return new InterruptFault; + } else { + return NoFault; } + } + + void + updateIntrInfo(ThreadContext *tc) + { + assert(newInfoSet); + tc->setMiscRegNoEffect(IPR_ISR, newSummary); + tc->setMiscRegNoEffect(IPR_INTID, newIpl); + newInfoSet = false; + } +}; - private: - bool newInfoSet; - int newIpl; - int newSummary; - }; -} +} // namespace AlphaISA -#endif +#endif // __ARCH_ALPHA_INTERRUPT_HH__ |