summaryrefslogtreecommitdiff
path: root/src/arch/sparc/interrupts.hh
diff options
context:
space:
mode:
authorAli Saidi <saidi@eecs.umich.edu>2007-03-03 17:22:47 -0500
committerAli Saidi <saidi@eecs.umich.edu>2007-03-03 17:22:47 -0500
commit36f43ff6a5618154f6388650cc2a8526efdd7b30 (patch)
treecfdd7163931c436ed6d04aec815c125e5dedef4d /src/arch/sparc/interrupts.hh
parentf892608ff7c9898dcbed6dd553632ac2caf4b1ae (diff)
downloadgem5-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.hh163
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 &section)
{
- UNSERIALIZE_ARRAY(interrupts,num_interrupt_types);
- UNSERIALIZE_SCALAR(numPosted);
+ UNSERIALIZE_ARRAY(interrupts,NumInterruptTypes);
+ UNSERIALIZE_SCALAR(intStatus);
}
};
} // namespace SPARC_ISA