From a068d6db0fff7056abb06bb8a99494b63bd169e1 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 13 Mar 2007 00:05:52 -0400 Subject: [PATCH] fix interrupting during a quisce on sparc src/arch/sparc/ua2005.cc: fix interrupting when quisced. Since sticks correspond to instructions when not quisced we need to check if were suspended and interrupt at the guess time src/base/traceflags.py: add trace flag for Iob src/cpu/simple/base.cc: Use Quisce instead of IPI trace flag src/dev/sparc/iob.cc: add some Dprintfs --HG-- extra : convert_revision : 72e18fcc750ad1e4b2bb67b19b354eaffc6af6d5 --- src/arch/sparc/ua2005.cc | 9 +++++++-- src/base/traceflags.py | 1 + src/cpu/simple/base.cc | 2 +- src/dev/sparc/iob.cc | 18 ++++++++++++++++++ 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc index 865280038..48e97a531 100644 --- a/src/arch/sparc/ua2005.cc +++ b/src/arch/sparc/ua2005.cc @@ -195,6 +195,7 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) panic("No support for setting spec_en bit\n"); setRegNoEffect(miscReg, bits(val,0,0)); if (!bits(val,0,0)) { + DPRINTF(Quiesce, "Cpu executed quiescing instruction\n"); // Time to go to sleep tc->suspend(); if (tc->getKernelStats()) @@ -307,7 +308,7 @@ MiscRegFile::processSTickCompare(ThreadContext *tc) tc->getCpuPtr()->instCount(); assert(ticks >= 0 && "stick compare missed interrupt cycle"); - if (ticks == 0) { + if (ticks == 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))) { @@ -324,11 +325,15 @@ MiscRegFile::processHSTickCompare(ThreadContext *tc) // we're actually at the correct cycle or we need to wait a little while // more int ticks; + if ( tc->status() == ThreadContext::Halted || + tc->status() == ThreadContext::Unallocated) + return; + ticks = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) - tc->getCpuPtr()->instCount(); assert(ticks >= 0 && "hstick compare missed interrupt cycle"); - if (ticks == 0) { + if (ticks == 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))) { diff --git a/src/base/traceflags.py b/src/base/traceflags.py index cb17d98d3..a36db1963 100644 --- a/src/base/traceflags.py +++ b/src/base/traceflags.py @@ -116,6 +116,7 @@ baseFlags = [ 'ISP', 'IdeCtrl', 'IdeDisk', + 'Iob', 'Interrupt', 'LLSC', 'LSQ', diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index f6c109127..9feb09851 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -301,7 +301,7 @@ BaseSimpleCPU::post_interrupt(int int_num, int index) BaseCPU::post_interrupt(int_num, index); if (thread->status() == ThreadContext::Suspended) { - DPRINTF(IPI,"Suspended Processor awoke\n"); + DPRINTF(Quiesce,"Suspended Processor awoke\n"); thread->activate(); } } diff --git a/src/dev/sparc/iob.cc b/src/dev/sparc/iob.cc index 6bd40b631..e686e51f7 100644 --- a/src/dev/sparc/iob.cc +++ b/src/dev/sparc/iob.cc @@ -192,6 +192,8 @@ Iob::writeIob(PacketPtr pkt) data = pkt->get(); intMan[index].cpu = bits(data,12,8); intMan[index].vector = bits(data,5,0); + DPRINTF(Iob, "Wrote IntMan %d cpu %d, vec %d\n", index, + intMan[index].cpu, intMan[index].vector); return; } @@ -201,11 +203,14 @@ Iob::writeIob(PacketPtr pkt) intCtl[index].mask = bits(data,2,2); if (bits(data,1,1)) intCtl[index].pend = false; + DPRINTF(Iob, "Wrote IntCtl %d pend %d cleared %d\n", index, + intCtl[index].pend, bits(data,2,2)); return; } if (accessAddr == JIntVecAddr) { jIntVec = bits(pkt->get(), 5,0); + DPRINTF(Iob, "Wrote jIntVec %d\n", jIntVec); return; } @@ -237,11 +242,15 @@ Iob::writeJBus(PacketPtr pkt) index = (accessAddr - JIntBusyAddr) >> 3; data = pkt->get(); jIntBusy[index].busy = bits(data,5,5); + DPRINTF(Iob, "Wrote jIntBusy index %d busy: %d\n", index, + jIntBusy[index].busy); return; } if (accessAddr == JIntABusyAddr) { data = pkt->get(); jIntBusy[cpuid].busy = bits(data,5,5); + DPRINTF(Iob, "Wrote jIntBusy index %d busy: %d\n", cpuid, + jIntBusy[cpuid].busy); return; }; @@ -256,6 +265,8 @@ Iob::receiveDeviceInterrupt(DeviceId devid) return; intCtl[devid].mask = true; intCtl[devid].pend = true; + DPRINTF(Iob, "Receiving Device interrupt: %d for cpu %d vec %d\n", + devid, intMan[devid].cpu, intMan[devid].vector); ic->post(intMan[devid].cpu, SparcISA::IT_INT_VEC, intMan[devid].vector); } @@ -269,6 +280,8 @@ Iob::generateIpi(Type type, int cpu_id, int vector) switch (type) { case 0: // interrupt + DPRINTF(Iob, "Generating interrupt because of I/O write to cpu: %d vec %d\n", + cpu_id, vector); ic->post(cpu_id, SparcISA::IT_INT_VEC, vector); break; case 1: // reset @@ -279,9 +292,11 @@ Iob::generateIpi(Type type, int cpu_id, int vector) sys->threadContexts[cpu_id]->activate(); break; case 2: // idle -- this means stop executing and don't wake on interrupts + DPRINTF(Iob, "Idling CPU because of I/O write cpu: %d\n", cpu_id); sys->threadContexts[cpu_id]->halt(); break; case 3: // resume + DPRINTF(Iob, "Resuming CPU because of I/O write cpu: %d\n", cpu_id); sys->threadContexts[cpu_id]->activate(); break; default: @@ -297,6 +312,9 @@ Iob::receiveJBusInterrupt(int cpu_id, int source, uint64_t d0, uint64_t d1) if (jIntBusy[cpu_id].busy) return false; + DPRINTF(Iob, "Receiving jBus interrupt: %d for cpu %d vec %d\n", + source, cpu_id, jIntVec); + jIntBusy[cpu_id].busy = true; jIntBusy[cpu_id].source = source; jBusData0[cpu_id] = d0; -- 2.30.2