Rewrote interrupt code to handle masking correctly and changed every

interrupt to use a different subnumber since both devices could
interrupt at the same time and we don't want to loose one.

dev/tsunami_cchip.cc:
    rewrote interrupt code to handle interrupt mask clearing correctly
dev/tsunami_cchip.hh:
    changed (post/clear)DRIR to use a interrupt number rather than a vecotr
dev/tsunami_io.cc:
    updated for new post/clearDRIR calls

--HG--
extra : convert_revision : 5b39f5e15a66d5eb6e689e6ece62f99b5fa735ab
This commit is contained in:
Ali Saidi 2004-02-15 23:56:44 -05:00
parent 9984412671
commit de5fa66714
3 changed files with 65 additions and 64 deletions

View file

@ -134,6 +134,7 @@ TsunamiCChip::write(MemReqPtr &req, const uint8_t *data)
req->vaddr, req->size); req->vaddr, req->size);
Addr daddr = (req->paddr - (addr & PA_IMPL_MASK)) >> 6; Addr daddr = (req->paddr - (addr & PA_IMPL_MASK)) >> 6;
uint64_t olddim;
switch (req->size) { switch (req->size) {
@ -161,46 +162,46 @@ TsunamiCChip::write(MemReqPtr &req, const uint8_t *data)
panic("TSDEV_CC_AARx write not implemeted\n"); panic("TSDEV_CC_AARx write not implemeted\n");
return No_Fault; return No_Fault;
case TSDEV_CC_DIM0: case TSDEV_CC_DIM0:
dim[0] = *(uint64_t*)data; case TSDEV_CC_DIM1:
if (dim[0] & drir) { case TSDEV_CC_DIM2:
dir[0] = dim[0] & drir; case TSDEV_CC_DIM3:
if (!dirInterrupting[0]) { int number;
dirInterrupting[0] = true; if(daddr == TSDEV_CC_DIM0)
tsunami->intrctrl->post(0, TheISA::INTLEVEL_IRQ1, 0); number = 0;
else if(daddr == TSDEV_CC_DIM1)
number = 1;
else if(daddr == TSDEV_CC_DIM2)
number = 2;
else
number = 3;
olddim = dim[number];
dim[number] = *(uint64_t*)data;
dir[number] = dim[number] & drir;
uint64_t bitvector;
for(int x = 0; x < 64; x++)
{
bitvector = 1 << x;
// Figure out which bits have changed
if ((dim[number] & bitvector) != (olddim & bitvector))
{
// The bit is now set and it wasn't before (set)
if((dim[number] & bitvector) && (dir[number] & bitvector))
{
tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x);
DPRINTF(Tsunami, "posting dir interrupt to cpu 0\n"); DPRINTF(Tsunami, "posting dir interrupt to cpu 0\n");
} }
else if (!(dir[number] & bitvector))
{
// The bit was set and now its now clear and
// we were interrupting on that bit before
tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x);
DPRINTF(Tsunami, "dim write resulting in clear"
"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; return No_Fault;
@ -209,25 +210,20 @@ TsunamiCChip::write(MemReqPtr &req, const uint8_t *data)
case TSDEV_CC_DIR2: case TSDEV_CC_DIR2:
case TSDEV_CC_DIR3: case TSDEV_CC_DIR3:
panic("TSDEV_CC_DIR write not implemented\n"); panic("TSDEV_CC_DIR write not implemented\n");
return No_Fault;
case TSDEV_CC_DRIR: case TSDEV_CC_DRIR:
panic("TSDEV_CC_DRIR write not implemented\n"); panic("TSDEV_CC_DRIR write not implemented\n");
return No_Fault;
case TSDEV_CC_PRBEN: case TSDEV_CC_PRBEN:
panic("TSDEV_CC_PRBEN write not implemented\n"); panic("TSDEV_CC_PRBEN write not implemented\n");
return No_Fault;
case TSDEV_CC_IIC0: case TSDEV_CC_IIC0:
case TSDEV_CC_IIC1: case TSDEV_CC_IIC1:
case TSDEV_CC_IIC2: case TSDEV_CC_IIC2:
case TSDEV_CC_IIC3: case TSDEV_CC_IIC3:
panic("TSDEV_CC_IICx write not implemented\n"); panic("TSDEV_CC_IICx write not implemented\n");
return No_Fault;
case TSDEV_CC_MPR0: case TSDEV_CC_MPR0:
case TSDEV_CC_MPR1: case TSDEV_CC_MPR1:
case TSDEV_CC_MPR2: case TSDEV_CC_MPR2:
case TSDEV_CC_MPR3: case TSDEV_CC_MPR3:
panic("TSDEV_CC_MPRx write not implemented\n"); panic("TSDEV_CC_MPRx write not implemented\n");
return No_Fault;
default: default:
panic("default in cchip read reached, accessing 0x%x\n"); panic("default in cchip read reached, accessing 0x%x\n");
} }
@ -246,35 +242,40 @@ TsunamiCChip::write(MemReqPtr &req, const uint8_t *data)
} }
void void
TsunamiCChip::postDRIR(uint64_t bitvector) TsunamiCChip::postDRIR(uint32_t interrupt)
{ {
uint64_t bitvector = 0x1 << interrupt;
drir |= bitvector; drir |= bitvector;
for(int i=0; i < Tsunami::Max_CPUs; i++) { for(int i=0; i < Tsunami::Max_CPUs; i++) {
if (bitvector & dim[i]) { dir[i] = dim[i] & drir;
dir[i] |= bitvector; if (dim[i] & bitvector) {
if (!dirInterrupting[i]) { tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ1, interrupt);
dirInterrupting[i] = true; DPRINTF(Tsunami, "posting dir interrupt to cpu %d,"
tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ1, 0); "interrupt %d\n",i, interrupt);
DPRINTF(Tsunami, "posting dir interrupt to cpu %d\n",i);
}
} }
} }
} }
void void
TsunamiCChip::clearDRIR(uint64_t bitvector) TsunamiCChip::clearDRIR(uint32_t interrupt)
{
uint64_t bitvector = 0x1 << interrupt;
if (drir & bitvector)
{ {
drir &= ~bitvector; drir &= ~bitvector;
for(int i=0; i < Tsunami::Max_CPUs; i++) { for(int i=0; i < Tsunami::Max_CPUs; i++) {
dir[i] &= ~bitvector; if (dir[i] & bitvector) {
if (!dir[i]) { tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ1, interrupt);
dirInterrupting[i] = false; DPRINTF(Tsunami, "clearing dir interrupt to cpu %d,"
tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ1, 0); "interrupt %d\n",i, interrupt);
DPRINTF(Tsunami, "clearing dir interrupt to cpu %d\n", i);
} }
dir[i] = dim[i] & drir;
} }
} }
else
DPRINTF(Tsunami, "Spurrious clear? interrupt %d\n", interrupt);
}
void void
TsunamiCChip::serialize(std::ostream &os) TsunamiCChip::serialize(std::ostream &os)

View file

@ -79,8 +79,8 @@ class TsunamiCChip : public FunctionalMemory
virtual Fault read(MemReqPtr &req, uint8_t *data); virtual Fault read(MemReqPtr &req, uint8_t *data);
virtual Fault write(MemReqPtr &req, const uint8_t *data); virtual Fault write(MemReqPtr &req, const uint8_t *data);
void postDRIR(uint64_t bitvector); void postDRIR(uint32_t interrupt);
void clearDRIR(uint64_t bitvector); void clearDRIR(uint32_t interrupt);
virtual void serialize(std::ostream &os); virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section); virtual void unserialize(Checkpoint *cp, const std::string &section);

View file

@ -237,7 +237,7 @@ TsunamiIO::write(MemReqPtr &req, const uint8_t *data)
mask1 = *(uint8_t*)data; mask1 = *(uint8_t*)data;
if ((picr & mask1) && !picInterrupting) { if ((picr & mask1) && !picInterrupting) {
picInterrupting = true; picInterrupting = true;
tsunami->cchip->postDRIR(uint64_t(1) << 55); tsunami->cchip->postDRIR(55);
DPRINTF(Tsunami, "posting pic interrupt to cchip\n"); DPRINTF(Tsunami, "posting pic interrupt to cchip\n");
} }
return No_Fault; return No_Fault;
@ -326,7 +326,7 @@ TsunamiIO::postPIC(uint8_t bitvector)
picr |= bitvector; picr |= bitvector;
if ((picr & mask1) && !picInterrupting) { if ((picr & mask1) && !picInterrupting) {
picInterrupting = true; picInterrupting = true;
tsunami->cchip->postDRIR(uint64_t(1) << 55); tsunami->cchip->postDRIR(55);
DPRINTF(Tsunami, "posting pic interrupt to cchip\n"); DPRINTF(Tsunami, "posting pic interrupt to cchip\n");
} }
} }
@ -338,7 +338,7 @@ TsunamiIO::clearPIC(uint8_t bitvector)
picr &= ~bitvector; picr &= ~bitvector;
if (!(picr & mask1)) { if (!(picr & mask1)) {
picInterrupting = false; picInterrupting = false;
tsunami->cchip->clearDRIR(uint64_t(1) << 55); tsunami->cchip->clearDRIR(55);
DPRINTF(Tsunami, "clearing pic interrupt to cchip\n"); DPRINTF(Tsunami, "clearing pic interrupt to cchip\n");
} }
} }