summaryrefslogtreecommitdiff
path: root/src/dev/sparc/iob.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/dev/sparc/iob.cc')
-rw-r--r--src/dev/sparc/iob.cc47
1 files changed, 42 insertions, 5 deletions
diff --git a/src/dev/sparc/iob.cc b/src/dev/sparc/iob.cc
index 2cff02a99..e686e51f7 100644
--- a/src/dev/sparc/iob.cc
+++ b/src/dev/sparc/iob.cc
@@ -38,6 +38,7 @@
#include <cstring>
#include "arch/sparc/isa_traits.hh"
+#include "arch/sparc/faults.hh"
#include "base/trace.hh"
#include "cpu/intr_control.hh"
#include "dev/sparc/iob.hh"
@@ -45,6 +46,7 @@
#include "mem/port.hh"
#include "mem/packet_access.hh"
#include "sim/builder.hh"
+#include "sim/faults.hh"
#include "sim/system.hh"
Iob::Iob(Params *p)
@@ -190,6 +192,8 @@ Iob::writeIob(PacketPtr pkt)
data = pkt->get<uint64_t>();
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;
}
@@ -199,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<uint64_t>(), 5,0);
+ DPRINTF(Iob, "Wrote jIntVec %d\n", jIntVec);
return;
}
@@ -235,11 +242,15 @@ Iob::writeJBus(PacketPtr pkt)
index = (accessAddr - JIntBusyAddr) >> 3;
data = pkt->get<uint64_t>();
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<uint64_t>();
jIntBusy[cpuid].busy = bits(data,5,5);
+ DPRINTF(Iob, "Wrote jIntBusy index %d busy: %d\n", cpuid,
+ jIntBusy[cpuid].busy);
return;
};
@@ -254,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);
}
@@ -261,13 +274,34 @@ Iob::receiveDeviceInterrupt(DeviceId devid)
void
Iob::generateIpi(Type type, int cpu_id, int vector)
{
- // Only handle interrupts for the moment... Cpu Idle/reset/resume will be
- // later
- if (type != 0)
+ SparcISA::SparcFault<SparcISA::PowerOnReset> *por = new SparcISA::PowerOnReset();
+ if (cpu_id >= sys->getNumCPUs())
return;
- assert(type == 0);
- ic->post(cpu_id, SparcISA::IT_INT_VEC, 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
+ warn("Sending reset to CPU: %d\n", cpu_id);
+ if (vector != por->trapType())
+ panic("Don't know how to set non-POR reset to cpu\n");
+ por->invoke(sys->threadContexts[cpu_id]);
+ 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:
+ panic("Invalid type to generate ipi\n");
+ }
}
bool
@@ -278,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;