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:
parent
9984412671
commit
de5fa66714
3 changed files with 65 additions and 64 deletions
|
@ -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,34 +242,39 @@ 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
|
||||||
|
|
|
@ -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 §ion);
|
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue