/* Names for each interrupt, for debugging purposes. */
static const char *intr_names[INTR_CNT];
+/* Number of unexpected interrupts for each vector. An
+ unexpected interrupt is one that has no registered handler. */
+static unsigned int unexpected_cnt[INTR_CNT];
+
/* External interrupts are those generated by devices outside the
CPU, such as the timer. External interrupts run with
interrupts turned off, so they never nest, nor are they ever
/* Interrupt handlers. */
void intr_handler (struct intr_frame *args);
+static void unexpected_interrupt (const struct intr_frame *);
\f
/* Returns the current interrupt status. */
enum intr_level
spuriously due to a hardware fault or hardware race
condition. Ignore it. */
}
- else
- {
- /* No handler and not spurious. Invoke the unexpected
- interrupt handler. */
- intr_dump_frame (frame);
- PANIC ("Unexpected interrupt");
- }
+ else
+ unexpected_interrupt (frame);
/* Complete the processing of an external interrupt. */
if (external)
}
}
+/* Handles an unexpected interrupt with interrupt frame F. An
+ unexpected interrupt is one that has no registered handler. */
+static void
+unexpected_interrupt (const struct intr_frame *f)
+{
+ /* Count the number so far. */
+ unsigned int n = ++unexpected_cnt[f->vec_no];
+
+ /* If the number is a power of 2, print a message. This rate
+ limiting means that we get information about an uncommon
+ unexpected interrupt the first time and fairly often after
+ that, but one that occurs many times will not overwhelm the
+ console. */
+ if ((n & (n - 1)) == 0)
+ printf ("Unexpected interrupt %#04x (%s)\n",
+ f->vec_no, intr_names[f->vec_no]);
+}
+
/* Dumps interrupt frame F to the console, for debugging. */
void
intr_dump_frame (const struct intr_frame *f)