diff options
author | Ali Saidi <saidi@eecs.umich.edu> | 2007-03-03 17:22:47 -0500 |
---|---|---|
committer | Ali Saidi <saidi@eecs.umich.edu> | 2007-03-03 17:22:47 -0500 |
commit | 36f43ff6a5618154f6388650cc2a8526efdd7b30 (patch) | |
tree | cfdd7163931c436ed6d04aec815c125e5dedef4d /src/arch/sparc/interrupts.hh | |
parent | f892608ff7c9898dcbed6dd553632ac2caf4b1ae (diff) | |
download | gem5-36f43ff6a5618154f6388650cc2a8526efdd7b30.tar.xz |
Implement Niagara I/O interface and rework interrupts
configs/common/FSConfig.py:
Use binaries we've compiled instead of the ones that come with Legion
src/arch/alpha/interrupts.hh:
get rid of post(int int_type) and add a get_vec function that gets the interrupt vector for an interrupt number
src/arch/sparc/asi.cc:
Add AsiIsInterrupt() to AsiIsMmu()
src/arch/sparc/faults.cc:
src/arch/sparc/faults.hh:
Add InterruptVector type
src/arch/sparc/interrupts.hh:
rework interrupts. They are no longer cleared when created... A I/O or ASI read/write needs to happen before they are cleared
src/arch/sparc/isa_traits.hh:
Add the "interrupt" trap types to isa traits
src/arch/sparc/miscregfile.cc:
add names for all the misc registers and possible post an interrupt when TL is changed.
src/arch/sparc/miscregfile.hh:
Add a helper function to post an interrupt when pil < some set softint
src/arch/sparc/regfile.cc:
src/arch/sparc/regfile.hh:
InterruptLevel shouldn't really live here, moved to interrupt.hh
src/arch/sparc/tlb.cc:
Add interrupt ASIs to TLB
src/arch/sparc/ua2005.cc:
Add checkSoftInt to check if a softint needs to be posted
Check that a tickCompare isn't scheduled before scheduling one
Post and clear interrupts on queue writes and what not
src/base/bitfield.hh:
Add an helper function to return the msb that is set
src/cpu/base.cc:
src/cpu/base.hh:
get rid of post_interrupt(type) since it's no longer needed.. Add a way to see what interrupts are pending
src/cpu/intr_control.cc:
src/cpu/intr_control.hh:
src/dev/alpha/tsunami_cchip.cc:
src/python/m5/objects/IntrControl.py:
Make IntrControl have a system pointer rather than using a cpu pointer to get one
src/dev/sparc/SConscript:
add iob to SConsscrip
tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-atomic-dual/config.ini:
tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-atomic-dual/config.out:
tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-atomic/config.ini:
tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-atomic/config.out:
tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-timing-dual/config.ini:
tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-timing-dual/config.out:
tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-timing/config.ini:
tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-timing/config.out:
tests/quick/80.netperf-stream/ref/alpha/linux/twosys-tsunami-simple-atomic/config.ini:
tests/quick/80.netperf-stream/ref/alpha/linux/twosys-tsunami-simple-atomic/config.out:
update config.ini/out for intrcntrl not having a cpu pointer anymore
--HG--
extra : convert_revision : 38614f6b9ffc8f3c93949a94ff04b7d2987168dd
Diffstat (limited to 'src/arch/sparc/interrupts.hh')
-rw-r--r-- | src/arch/sparc/interrupts.hh | 163 |
1 files changed, 67 insertions, 96 deletions
diff --git a/src/arch/sparc/interrupts.hh b/src/arch/sparc/interrupts.hh index dc3b235fe..3234002c5 100644 --- a/src/arch/sparc/interrupts.hh +++ b/src/arch/sparc/interrupts.hh @@ -24,76 +24,80 @@ * 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 + * Lisa Hsu */ #ifndef __ARCH_SPARC_INTERRUPT_HH__ #define __ARCH_SPARC_INTERRUPT_HH__ #include "arch/sparc/faults.hh" +#include "arch/sparc/isa_traits.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 { private: - bool interrupts[num_interrupt_types]; - int numPosted; + uint64_t interrupts[NumInterruptTypes]; + uint64_t intStatus; public: Interrupts() { - for (int i = 0; i < num_interrupt_types; ++i) { - interrupts[i] = false; - } - numPosted = 0; + clear_all(); } - void post(int int_type) + int InterruptLevel(uint64_t softint) { - if (int_type < 0 || int_type >= num_interrupt_types) - panic("posting unknown interrupt!\n"); - if (interrupts[int_type] == false) { - interrupts[int_type] = true; - ++numPosted; - } + if (softint & 0x10000 || softint & 0x1) + return 14; + + int level = 15; + while (level > 0 && !(1 << level & softint)) + level--; + if (1 << level & softint) + return level; + return 0; } void post(int int_num, int index) { + DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); + assert(int_num >= 0 && int_num < NumInterruptTypes); + assert(index >= 0 && index < 64); + interrupts[int_num] |= ULL(1) << index; + intStatus |= ULL(1) << int_num; } void clear(int int_num, int index) { + DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); + assert(int_num >= 0 && int_num < NumInterruptTypes); + assert(index >= 0 && index < 64); + interrupts[int_num] &= ~(ULL(1) << index); + if (!interrupts[int_num]) + intStatus &= ~(ULL(1) << int_num); } void clear_all() { - + for (int i = 0; i < NumInterruptTypes; ++i) { + interrupts[i] = 0; + } + intStatus = 0; } bool check_interrupts(ThreadContext * tc) const { - if (numPosted) - return true; - else - return false; + return intStatus; } Fault getInterrupt(ThreadContext * tc) @@ -109,84 +113,45 @@ class Interrupts // 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; + if (interrupts[IT_HINTP]) { + // This will be cleaned by a HINTP write + return new HstickMatch; } - } else { - if (interrupts[hstick_match]) { - return NoFault; + if (interrupts[IT_INT_VEC]) { + // this will be cleared by an ASI read (or write) + return new InterruptVector; } - } } else { - if (interrupts[trap_level_zero]) { - if ((pstate & HPSTATE::tlz) && (tc->readMiscReg(MISCREG_TL) == 0)) { - interrupts[trap_level_zero] = false; - --numPosted; + if (interrupts[IT_TRAP_LEVEL_ZERO]) { + // this is cleared by deasserting HPSTATE::tlz return new TrapLevelZero; - } } - if (interrupts[hstick_match]) { - if (tc->readMiscReg(MISCREG_HINTP) & 1) { - interrupts[hstick_match] = false; - --numPosted; - return new HstickMatch; - } + // HStick matches always happen in priv mode (ie doesn't matter) + if (interrupts[IT_HINTP]) { + return new HstickMatch; + } + if (interrupts[IT_INT_VEC]) { + // this will be cleared by an ASI read (or write) + return new InterruptVector; } if (ie) { - if (interrupts[cpu_mondo]) { - interrupts[cpu_mondo] = false; - --numPosted; + if (interrupts[IT_CPU_MONDO]) { return new CpuMondo; } - if (interrupts[dev_mondo]) { - interrupts[dev_mondo] = false; - --numPosted; + if (interrupts[IT_DEV_MONDO]) { 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[IT_SOFT_INT]) { + return new + InterruptLevelN(InterruptLevel(interrupts[IT_SOFT_INT])); } - if (interrupts[resumable_error]) { - interrupts[resumable_error] = false; - --numPosted; + + if (interrupts[IT_RES_ERROR]) { return new ResumableError; } - } - } + } // !hpriv && ie + } // !hpriv return NoFault; } @@ -195,16 +160,22 @@ class Interrupts } + uint64_t get_vec(int int_num) + { + assert(int_num >= 0 && int_num < NumInterruptTypes); + return interrupts[int_num]; + } + void serialize(std::ostream &os) { - SERIALIZE_ARRAY(interrupts,num_interrupt_types); - SERIALIZE_SCALAR(numPosted); + SERIALIZE_ARRAY(interrupts,NumInterruptTypes); + SERIALIZE_SCALAR(intStatus); } void unserialize(Checkpoint *cp, const std::string §ion) { - UNSERIALIZE_ARRAY(interrupts,num_interrupt_types); - UNSERIALIZE_SCALAR(numPosted); + UNSERIALIZE_ARRAY(interrupts,NumInterruptTypes); + UNSERIALIZE_SCALAR(intStatus); } }; } // namespace SPARC_ISA |