* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "arch/sparc/interrupts.hh"
#include "arch/sparc/isa.hh"
#include "arch/sparc/kernel_stats.hh"
#include "arch/sparc/registers.hh"
#include "base/trace.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
+#include "debug/Quiesce.hh"
+#include "debug/Timer.hh"
+#include "sim/full_system.hh"
#include "sim/system.hh"
using namespace SparcISA;
// If PIL < 14, copy over the tm and sm bits
if (pil < 14 && softint & 0x10000)
- cpu->postInterrupt(IT_SOFT_INT, 16);
+ cpu->postInterrupt(0, IT_SOFT_INT, 16);
else
- cpu->clearInterrupt(IT_SOFT_INT, 16);
+ cpu->clearInterrupt(0, IT_SOFT_INT, 16);
if (pil < 14 && softint & 0x1)
- cpu->postInterrupt(IT_SOFT_INT, 0);
+ cpu->postInterrupt(0, IT_SOFT_INT, 0);
else
- cpu->clearInterrupt(IT_SOFT_INT, 0);
+ cpu->clearInterrupt(0, 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)
- cpu->postInterrupt(IT_SOFT_INT, bit);
+ cpu->postInterrupt(0, IT_SOFT_INT, bit);
else
- cpu->clearInterrupt(IT_SOFT_INT, bit);
+ cpu->clearInterrupt(0, IT_SOFT_INT, bit);
}
}
}
void
-ISA::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc)
+ISA::setFSReg(int miscReg, RegVal val, ThreadContext *tc)
{
BaseCPU *cpu = tc->getCpuPtr();
if (!(tick_cmpr & ~mask(63)) && time > 0) {
if (tickCompare->scheduled())
cpu->deschedule(tickCompare);
- cpu->schedule(tickCompare, curTick + time * cpu->ticks(1));
+ cpu->schedule(tickCompare, cpu->clockEdge(Cycles(time)));
}
- panic("writing to TICK compare register %#X\n", val);
+ DPRINTF(Timer, "writing to TICK compare register value %#X\n", val);
break;
case MISCREG_STICK_CMPR:
if (!(stick_cmpr & ~mask(63)) && time > 0) {
if (sTickCompare->scheduled())
cpu->deschedule(sTickCompare);
- cpu->schedule(sTickCompare, curTick + time * cpu->ticks(1));
+ cpu->schedule(sTickCompare, cpu->clockEdge(Cycles(time)));
}
DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val);
break;
case MISCREG_PSTATE:
setMiscRegNoEffect(miscReg, val);
+ break;
case MISCREG_PIL:
setMiscRegNoEffect(miscReg, val);
case MISCREG_HINTP:
setMiscRegNoEffect(miscReg, val);
if (hintp)
- cpu->postInterrupt(IT_HINTP, 0);
+ cpu->postInterrupt(0, IT_HINTP, 0);
else
- cpu->clearInterrupt(IT_HINTP, 0);
+ cpu->clearInterrupt(0, IT_HINTP, 0);
break;
case MISCREG_HTBA:
case MISCREG_QUEUE_CPU_MONDO_TAIL:
setMiscRegNoEffect(miscReg, val);
if (cpu_mondo_head != cpu_mondo_tail)
- cpu->postInterrupt(IT_CPU_MONDO, 0);
+ cpu->postInterrupt(0, IT_CPU_MONDO, 0);
else
- cpu->clearInterrupt(IT_CPU_MONDO, 0);
+ cpu->clearInterrupt(0, IT_CPU_MONDO, 0);
break;
case MISCREG_QUEUE_DEV_MONDO_HEAD:
case MISCREG_QUEUE_DEV_MONDO_TAIL:
setMiscRegNoEffect(miscReg, val);
if (dev_mondo_head != dev_mondo_tail)
- cpu->postInterrupt(IT_DEV_MONDO, 0);
+ cpu->postInterrupt(0, IT_DEV_MONDO, 0);
else
- cpu->clearInterrupt(IT_DEV_MONDO, 0);
+ cpu->clearInterrupt(0, IT_DEV_MONDO, 0);
break;
case MISCREG_QUEUE_RES_ERROR_HEAD:
case MISCREG_QUEUE_RES_ERROR_TAIL:
setMiscRegNoEffect(miscReg, val);
if (res_error_head != res_error_tail)
- cpu->postInterrupt(IT_RES_ERROR, 0);
+ cpu->postInterrupt(0, IT_RES_ERROR, 0);
else
- cpu->clearInterrupt(IT_RES_ERROR, 0);
+ cpu->clearInterrupt(0, IT_RES_ERROR, 0);
break;
case MISCREG_QUEUE_NRES_ERROR_HEAD:
case MISCREG_QUEUE_NRES_ERROR_TAIL:
if (!(hstick_cmpr & ~mask(63)) && time > 0) {
if (hSTickCompare->scheduled())
cpu->deschedule(hSTickCompare);
- cpu->schedule(hSTickCompare, curTick + time * cpu->ticks(1));
+ cpu->schedule(hSTickCompare, cpu->clockEdge(Cycles(time)));
}
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
- setMiscRegNoEffect(miscReg, val | HPSTATE::id);
-#if FULL_SYSTEM
- if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv))
- cpu->postInterrupt(IT_TRAP_LEVEL_ZERO, 0);
- else
- cpu->clearInterrupt(IT_TRAP_LEVEL_ZERO, 0);
-#endif
- break;
+ {
+ HPSTATE newVal = val;
+ newVal.id = 1;
+ // T1000 spec says impl. dependent val must always be 1
+ setMiscRegNoEffect(miscReg, newVal);
+ newVal = hpstate;
+ if (newVal.tlz && tl == 0 && !newVal.hpriv)
+ cpu->postInterrupt(0, IT_TRAP_LEVEL_ZERO, 0);
+ else
+ cpu->clearInterrupt(0, IT_TRAP_LEVEL_ZERO, 0);
+ break;
+ }
case MISCREG_HTSTATE:
setMiscRegNoEffect(miscReg, val);
break;
DPRINTF(Quiesce, "Cpu executed quiescing instruction\n");
// Time to go to sleep
tc->suspend();
- if (tc->getKernelStats())
+ if (FullSystem && tc->getKernelStats())
tc->getKernelStats()->quiesce();
}
break;
}
}
-MiscReg
+RegVal
ISA::readFSReg(int miscReg, ThreadContext * tc)
{
uint64_t temp;
// since our microcode instructions take two cycles we need to check if
// we're actually at the correct cycle or we need to wait a little while
// more
- int ticks;
- ticks = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) -
+ int delay;
+ delay = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) -
cpu->instCount();
- assert(ticks >= 0 && "stick compare missed interrupt cycle");
+ assert(delay >= 0 && "stick compare missed interrupt cycle");
- if (ticks == 0 || tc->status() == ThreadContext::Suspended) {
+ if (delay == 0 || tc->status() == ThreadContext::Suspended) {
DPRINTF(Timer, "STick compare cycle reached at %#x\n",
(stick_cmpr & mask(63)));
if (!(tc->readMiscRegNoEffect(MISCREG_STICK_CMPR) & (ULL(1) << 63))) {
setMiscReg(MISCREG_SOFTINT, softint | (ULL(1) << 16), tc);
}
} else {
- cpu->schedule(sTickCompare, curTick + ticks * cpu->ticks(1));
+ cpu->schedule(sTickCompare, cpu->clockEdge(Cycles(delay)));
}
}
// since our microcode instructions take two cycles we need to check if
// we're actually at the correct cycle or we need to wait a little while
// more
- int ticks;
+ int delay;
if ( tc->status() == ThreadContext::Halted)
return;
- ticks = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
+ delay = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
cpu->instCount();
- assert(ticks >= 0 && "hstick compare missed interrupt cycle");
+ assert(delay >= 0 && "hstick compare missed interrupt cycle");
- if (ticks == 0 || tc->status() == ThreadContext::Suspended) {
+ if (delay == 0 || tc->status() == ThreadContext::Suspended) {
DPRINTF(Timer, "HSTick compare cycle reached at %#x\n",
(stick_cmpr & mask(63)));
if (!(tc->readMiscRegNoEffect(MISCREG_HSTICK_CMPR) & (ULL(1) << 63))) {
}
// Need to do something to cause interrupt to happen here !!! @todo
} else {
- cpu->schedule(hSTickCompare, curTick + ticks * cpu->ticks(1));
+ cpu->schedule(hSTickCompare, cpu->clockEdge(Cycles(delay)));
}
}