+void
+TsunamiCChip::clearIPI(uint64_t ipintr)
+{
+ int numcpus = tsunami->intrctrl->cpu->system->execContexts.size();
+ assert(numcpus <= Tsunami::Max_CPUs);
+
+ if (ipintr) {
+ for (int cpunum=0; cpunum < numcpus; cpunum++) {
+ // Check each cpu bit
+ uint64_t cpumask = ULL(1) << cpunum;
+ if (ipintr & cpumask) {
+ // Check if there is a pending ipi
+ if (ipint & cpumask) {
+ ipint &= ~cpumask;
+ tsunami->intrctrl->clear(cpunum, TheISA::INTLEVEL_IRQ3, 0);
+ DPRINTF(IPI, "clear IPI IPI cpu=%d\n", cpunum);
+ }
+ else
+ warn("clear IPI for CPU=%d, but NO IPI\n", cpunum);
+ }
+ }
+ }
+ else
+ panic("Big IPI Clear, but not processors indicated\n");
+}
+
+void
+TsunamiCChip::clearITI(uint64_t itintr)
+{
+ int numcpus = tsunami->intrctrl->cpu->system->execContexts.size();
+ assert(numcpus <= Tsunami::Max_CPUs);
+
+ if (itintr) {
+ for (int i=0; i < numcpus; i++) {
+ uint64_t cpumask = ULL(1) << i;
+ if (itintr & cpumask & itint) {
+ tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ2, 0);
+ itint &= ~cpumask;
+ DPRINTF(Tsunami, "clearing rtc interrupt to cpu=%d\n", i);
+ }
+ }
+ }
+ else
+ panic("Big ITI Clear, but not processors indicated\n");
+}
+
+void
+TsunamiCChip::reqIPI(uint64_t ipreq)
+{
+ int numcpus = tsunami->intrctrl->cpu->system->execContexts.size();
+ assert(numcpus <= Tsunami::Max_CPUs);
+
+ if (ipreq) {
+ for (int cpunum=0; cpunum < numcpus; cpunum++) {
+ // Check each cpu bit
+ uint64_t cpumask = ULL(1) << cpunum;
+ if (ipreq & cpumask) {
+ // Check if there is already an ipi (bits 8:11)
+ if (!(ipint & cpumask)) {
+ ipint |= cpumask;
+ tsunami->intrctrl->post(cpunum, TheISA::INTLEVEL_IRQ3, 0);
+ DPRINTF(IPI, "send IPI cpu=%d\n", cpunum);
+ }
+ else
+ warn("post IPI for CPU=%d, but IPI already\n", cpunum);
+ }
+ }
+ }
+ else
+ panic("Big IPI Request, but not processors indicated\n");
+}
+
+