summaryrefslogtreecommitdiff
path: root/src/arch/sparc/ua2005.cc
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/ua2005.cc
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/ua2005.cc')
-rw-r--r--src/arch/sparc/ua2005.cc80
1 files changed, 70 insertions, 10 deletions
diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc
index ecb63bb9a..5b13cd041 100644
--- a/src/arch/sparc/ua2005.cc
+++ b/src/arch/sparc/ua2005.cc
@@ -34,6 +34,30 @@
using namespace SparcISA;
+
+void
+MiscRegFile::checkSoftInt(ThreadContext *tc)
+{
+ // If PIL < 14, copy over the tm and sm bits
+ if (pil < 14 && softint & 0x10000)
+ tc->getCpuPtr()->post_interrupt(IT_SOFT_INT,16);
+ else
+ tc->getCpuPtr()->clear_interrupt(IT_SOFT_INT,16);
+ if (pil < 14 && softint & 0x1)
+ tc->getCpuPtr()->post_interrupt(IT_SOFT_INT,0);
+ else
+ tc->getCpuPtr()->clear_interrupt(IT_SOFT_INT,0);
+
+ // Copy over any of the other bits that are set
+ for (int bit = 15; bit > 0; --bit) {
+ if (1 << bit & softint && bit > pil)
+ tc->getCpuPtr()->post_interrupt(IT_SOFT_INT,bit);
+ else
+ tc->getCpuPtr()->clear_interrupt(IT_SOFT_INT,bit);
+ }
+}
+
+
void
MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
ThreadContext *tc)
@@ -43,23 +67,25 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
/* Full system only ASRs */
case MISCREG_SOFTINT:
setReg(miscReg, val);;
+ checkSoftInt(tc);
break;
-
case MISCREG_SOFTINT_CLR:
return setRegWithEffect(MISCREG_SOFTINT, ~val & softint, tc);
case MISCREG_SOFTINT_SET:
- 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())
+ if ((tick_cmpr & ~mask(63)) && tickCompare->scheduled())
tickCompare->deschedule();
time = (tick_cmpr & mask(63)) - (tick & mask(63));
- if (!(tick_cmpr & ~mask(63)) && time > 0)
+ if (!(tick_cmpr & ~mask(63)) && time > 0) {
+ if (tickCompare->scheduled())
+ tickCompare->deschedule();
tickCompare->schedule(time * tc->getCpuPtr()->cycles(1));
+ }
panic("writing to TICK compare register %#X\n", val);
break;
@@ -71,8 +97,11 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
sTickCompare->deschedule();
time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) -
tc->getCpuPtr()->instCount();
- if (!(stick_cmpr & ~mask(63)) && time > 0)
+ if (!(stick_cmpr & ~mask(63)) && time > 0) {
+ if (sTickCompare->scheduled())
+ sTickCompare->deschedule();
sTickCompare->schedule(time * tc->getCpuPtr()->cycles(1) + curTick);
+ }
DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val);
break;
@@ -81,6 +110,7 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
case MISCREG_PIL:
setReg(miscReg, val);
+ checkSoftInt(tc);
break;
case MISCREG_HVER:
@@ -88,6 +118,11 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
case MISCREG_HINTP:
setReg(miscReg, val);
+ if (hintp)
+ tc->getCpuPtr()->post_interrupt(IT_HINTP,0);
+ else
+ tc->getCpuPtr()->clear_interrupt(IT_HINTP,0);
+ break;
case MISCREG_HTBA:
// clear lower 7 bits on writes.
@@ -96,14 +131,32 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
case MISCREG_QUEUE_CPU_MONDO_HEAD:
case MISCREG_QUEUE_CPU_MONDO_TAIL:
+ setReg(miscReg, val);
+ if (cpu_mondo_head != cpu_mondo_tail)
+ tc->getCpuPtr()->post_interrupt(IT_CPU_MONDO,0);
+ else
+ tc->getCpuPtr()->clear_interrupt(IT_CPU_MONDO,0);
+ break;
case MISCREG_QUEUE_DEV_MONDO_HEAD:
case MISCREG_QUEUE_DEV_MONDO_TAIL:
+ setReg(miscReg, val);
+ if (dev_mondo_head != dev_mondo_tail)
+ tc->getCpuPtr()->post_interrupt(IT_DEV_MONDO,0);
+ else
+ tc->getCpuPtr()->clear_interrupt(IT_DEV_MONDO,0);
+ break;
case MISCREG_QUEUE_RES_ERROR_HEAD:
case MISCREG_QUEUE_RES_ERROR_TAIL:
+ setReg(miscReg, val);
+ if (res_error_head != res_error_tail)
+ tc->getCpuPtr()->post_interrupt(IT_RES_ERROR,0);
+ else
+ tc->getCpuPtr()->clear_interrupt(IT_RES_ERROR,0);
+ break;
case MISCREG_QUEUE_NRES_ERROR_HEAD:
case MISCREG_QUEUE_NRES_ERROR_TAIL:
setReg(miscReg, val);
- //do something to post mondo interrupt
+ // This one doesn't have an interrupt to report to the guest OS
break;
case MISCREG_HSTICK_CMPR:
@@ -114,14 +167,23 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
hSTickCompare->deschedule();
time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
tc->getCpuPtr()->instCount();
- if (!(hstick_cmpr & ~mask(63)) && time > 0)
+ if (!(hstick_cmpr & ~mask(63)) && time > 0) {
+ if (hSTickCompare->scheduled())
+ hSTickCompare->deschedule();
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);
+#if FULL_SYSTEM
+ if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv))
+ tc->getCpuPtr()->post_interrupt(IT_TRAP_LEVEL_ZERO,0);
+ else
+ tc->getCpuPtr()->clear_interrupt(IT_TRAP_LEVEL_ZERO,0);
+#endif
break;
case MISCREG_HTSTATE:
case MISCREG_STRAND_STS_REG:
@@ -198,7 +260,6 @@ MiscRegFile::processSTickCompare(ThreadContext *tc)
DPRINTF(Timer, "STick compare cycle reached at %#x\n",
(stick_cmpr & mask(63)));
if (!(tc->readMiscReg(MISCREG_STICK_CMPR) & (ULL(1) << 63))) {
- tc->getCpuPtr()->post_interrupt(soft_interrupt);
setRegWithEffect(MISCREG_SOFTINT, softint | (ULL(1) << 16), tc);
}
} else
@@ -221,10 +282,9 @@ MiscRegFile::processHSTickCompare(ThreadContext *tc)
(stick_cmpr & mask(63)));
if (!(tc->readMiscReg(MISCREG_HSTICK_CMPR) & (ULL(1) << 63))) {
setRegWithEffect(MISCREG_HINTP, 1, tc);
- tc->getCpuPtr()->post_interrupt(hstick_match);
}
// Need to do something to cause interrupt to happen here !!! @todo
} else
- sTickCompare->schedule(ticks * tc->getCpuPtr()->cycles(1) + curTick);
+ hSTickCompare->schedule(ticks * tc->getCpuPtr()->cycles(1) + curTick);
}