for(int i=0; i < Tsunami::Max_CPUs; i++) {
dim[i] = 0;
dir[i] = 0;
+ dirInterrupting[i] = false;
}
drir = 0;
return No_Fault;
case TSDEV_CC_DIM0:
dim[0] = *(uint64_t*)data;
+ if (dim[0] & drir) {
+ dir[0] = dim[0] & drir;
+ if (!dirInterrupting[0]) {
+ dirInterrupting[0] = true;
+ tsunami->intrctrl->post(0, TheISA::INTLEVEL_IRQ1, 0);
+ DPRINTF(Tsunami, "posting dir interrupt to cpu 0\n");
+ }
+ }
return No_Fault;
case TSDEV_CC_DIM1:
dim[1] = *(uint64_t*)data;
+ if (dim[1] & drir) {
+ dir[1] = dim[1] & drir;
+ if (!dirInterrupting[1]) {
+ dirInterrupting[1] = true;
+ tsunami->intrctrl->post(1, TheISA::INTLEVEL_IRQ1, 0);
+ DPRINTF(Tsunami, "posting dir interrupt to cpu 1\n");
+ }
+ }
return No_Fault;
case TSDEV_CC_DIM2:
dim[2] = *(uint64_t*)data;
+ if (dim[2] & drir) {
+ dir[2] = dim[2] & drir;
+ if (!dirInterrupting[2]) {
+ dirInterrupting[2] = true;
+ tsunami->intrctrl->post(2, TheISA::INTLEVEL_IRQ1, 0);
+ DPRINTF(Tsunami, "posting dir interrupt to cpu 2\n");
+ }
+ }
return No_Fault;
case TSDEV_CC_DIM3:
dim[3] = *(uint64_t*)data;
+ if ((dim[3] & drir) /*And Not Already Int*/) {
+ dir[3] = dim[3] & drir;
+ if (!dirInterrupting[3]) {
+ dirInterrupting[3] = true;
+ tsunami->intrctrl->post(3, TheISA::INTLEVEL_IRQ1, 0);
+ DPRINTF(Tsunami, "posting dir interrupt to cpu 3\n");
+ }
+ }
return No_Fault;
case TSDEV_CC_DIR0:
case TSDEV_CC_DIR1:
return No_Fault;
}
+void
+TsunamiCChip::postDRIR(uint64_t bitvector)
+{
+ drir |= bitvector;
+ for(int i=0; i < Tsunami::Max_CPUs; i++) {
+ if (bitvector & dim[i]) {
+ dir[i] |= bitvector;
+ if (!dirInterrupting[i]) {
+ dirInterrupting[i] = true;
+ tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ1, 0);
+ DPRINTF(Tsunami, "posting dir interrupt to cpu %d\n",i);
+ }
+ }
+ }
+}
+
+void
+TsunamiCChip::clearDRIR(uint64_t bitvector)
+{
+ drir &= ~bitvector;
+ for(int i=0; i < Tsunami::Max_CPUs; i++) {
+ dir[i] &= ~bitvector;
+ if (!dir[i]) {
+ dirInterrupting[i] = false;
+ tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ1, 0);
+ DPRINTF(Tsunami, "clearing dir interrupt to cpu %d\n", i);
+
+ }
+ }
+}
+
void
TsunamiCChip::serialize(std::ostream &os)
{
Tsunami *tsunami;
uint64_t dim[Tsunami::Max_CPUs];
uint64_t dir[Tsunami::Max_CPUs];
+ bool dirInterrupting[Tsunami::Max_CPUs];
uint64_t drir;
public:
virtual Fault read(MemReqPtr req, uint8_t *data);
virtual Fault write(MemReqPtr req, const uint8_t *data);
+ void postDRIR(uint64_t bitvector);
+ void clearDRIR(uint64_t bitvector);
+
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string §ion);
timerData = 0;
set_time(init_time == 0 ? time(NULL) : init_time);
uip = 1;
+ picr = 0;
+ picInterrupting = false;
}
void
switch(daddr) {
case TSDEV_PIC1_MASK:
mask1 = *(uint8_t*)data;
+ if ((picr & mask1) && !picInterrupting) {
+ picInterrupting = true;
+ tsunami->cchip->postDRIR(uint64_t(1) << 55);
+ DPRINTF(Tsunami, "posting pic interrupt to cchip\n");
+ }
return No_Fault;
case TSDEV_PIC2_MASK:
mask2 = *(uint8_t*)data;
+ //PIC2 Not implemented to interrupt
return No_Fault;
case TSDEV_DMA1_RESET:
return No_Fault;
return No_Fault;
}
+void
+TsunamiIO::postPIC(uint8_t bitvector)
+{
+ //PIC2 Is not implemented, because nothing of interest there
+ picr |= bitvector;
+ if ((picr & mask1) && !picInterrupting) {
+ picInterrupting = true;
+ tsunami->cchip->postDRIR(uint64_t(1) << 55);
+ DPRINTF(Tsunami, "posting pic interrupt to cchip\n");
+ }
+}
+
+void
+TsunamiIO::clearPIC(uint8_t bitvector)
+{
+ //PIC2 Is not implemented, because nothing of interest there
+ picr &= ~bitvector;
+ if (!(picr & mask1)) {
+ picInterrupting = false;
+ tsunami->cchip->clearDRIR(uint64_t(1) << 55);
+ DPRINTF(Tsunami, "clearing pic interrupt to cchip\n");
+ }
+}
+
void
TsunamiIO::serialize(std::ostream &os)
{
uint8_t mode1;
uint8_t mode2;
+ uint8_t picr; //Raw PIC interrput register, before masking
+ bool picInterrupting;
+
Tsunami *tsunami;
/* This timer is initilized, but after I wrote the code
virtual Fault read(MemReqPtr req, uint8_t *data);
virtual Fault write(MemReqPtr req, const uint8_t *data);
+ void postPIC(uint8_t bitvector);
+ void clearPIC(uint8_t bitvector);
+
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string §ion);
};