summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Binkert <binkertn@umich.edu>2004-08-20 11:40:57 -0400
committerNathan Binkert <binkertn@umich.edu>2004-08-20 11:40:57 -0400
commit0b0a6778c96c3ac3e3f979d655de0ae595232507 (patch)
treec2df1ee0c73596c0bf79bb6ab554c103e8bbe735
parentfbbdc531b828d45b8862f2d7b9b32881d316faf0 (diff)
downloadgem5-0b0a6778c96c3ac3e3f979d655de0ae595232507.tar.xz
Fixup interrupting of the ethernet device.
dev/ns_gige.cc: clean up the interrupt handling code so that it is simpler and less prone to bugs. I hope I removed the bug where the: assert(intrTick >= curTick || intrTick == 0); would get triggered. I'm pretty sure that was due to intrTick not being cleared when the interrupt was cleared. This code probably still needs to be looked at more closely to make sure interrupts are not missed. --HG-- extra : convert_revision : 61e2eb043540f2534a80c9b633006a71e7d6e282
-rw-r--r--dev/ns_gige.cc72
1 files changed, 34 insertions, 38 deletions
diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc
index f7f56d39b..87ac5b593 100644
--- a/dev/ns_gige.cc
+++ b/dev/ns_gige.cc
@@ -987,61 +987,50 @@ NSGigE::cpuIntrPost(Tick when)
* @todo this warning should be removed and the intrTick code should
* be fixed.
*/
- if (intrTick < curTick && intrTick != 0) {
- warn("intrTick < curTick !!! intrTick=%d curTick=%d\n",
- intrTick, curTick);
- intrTick = 0;
- }
- assert((intrTick >= curTick) || (intrTick == 0));
- if (when > intrTick && intrTick != 0)
+ assert(when >= curTick);
+ assert(intrTick >= curTick || intrTick == 0);
+ if (when > intrTick && intrTick != 0) {
+ DPRINTF(EthernetIntr, "don't need to schedule event...intrTick=%d\n",
+ intrTick);
return;
+ }
intrTick = when;
-
- if (intrEvent) {
- intrEvent->squash();
- intrEvent = 0;
+ if (intrTick < curTick) {
+ debug_break();
+ intrTick = curTick;
}
- if (when < curTick) {
- cpuInterrupt();
- } else {
- DPRINTF(EthernetIntr,
- "going to schedule an interrupt for intrTick=%d\n",
- intrTick);
- intrEvent = new IntrEvent(this, true);
- intrEvent->schedule(intrTick);
- }
+ DPRINTF(EthernetIntr, "going to schedule an interrupt for intrTick=%d\n",
+ intrTick);
+
+ if (intrEvent)
+ intrEvent->squash();
+ intrEvent = new IntrEvent(this, true);
+ intrEvent->schedule(intrTick);
}
void
NSGigE::cpuInterrupt()
{
- // Don't send an interrupt if there's already one
- if (cpuPendingIntr) {
- DPRINTF(EthernetIntr,
- "would send an interrupt now, but there's already pending\n");
- intrTick = 0;
- return;
- }
- // Don't send an interrupt if it's supposed to be delayed
- if (intrTick > curTick) {
- DPRINTF(EthernetIntr,
- "an interrupt is scheduled for %d, wait til then\n",
- intrTick);
- return;
- }
+ assert(intrTick == curTick);
// Whether or not there's a pending interrupt, we don't care about
// it anymore
intrEvent = 0;
intrTick = 0;
- // Send interrupt
- cpuPendingIntr = true;
+ // Don't send an interrupt if there's already one
+ if (cpuPendingIntr) {
+ DPRINTF(EthernetIntr,
+ "would send an interrupt now, but there's already pending\n");
+ } else {
+ // Send interrupt
+ cpuPendingIntr = true;
- DPRINTF(EthernetIntr, "posting cchip interrupt\n");
- tsunami->cchip->postDRIR(configData->config.hdr.pci0.interruptLine);
+ DPRINTF(EthernetIntr, "posting cchip interrupt\n");
+ tsunami->cchip->postDRIR(configData->config.hdr.pci0.interruptLine);
+ }
}
void
@@ -1050,6 +1039,13 @@ NSGigE::cpuIntrClear()
if (!cpuPendingIntr)
return;
+ if (intrEvent) {
+ intrEvent->squash();
+ intrEvent = 0;
+ }
+
+ intrTick = 0;
+
cpuPendingIntr = false;
DPRINTF(EthernetIntr, "clearing cchip interrupt\n");