usb.patch, with conflicts and some warnings fixed
[pintos-anon] / src / threads / interrupt.c
index 9ffd873540b803ca3414b83f10c6da4e8c4b2f54..27f470861a22de11b725475b731d2a11afdfafcc 100644 (file)
@@ -17,6 +17,8 @@
 #define PIC0_DATA      0x21    /* Master PIC data register address. */
 #define PIC1_CTRL      0xa0    /* Slave PIC control register address. */
 #define PIC1_DATA      0xa1    /* Slave PIC data register address. */
+#define IRQ_CASCADE0   2
+#define IRQ_CASCADE1   9
 
 /* Number of x86 interrupts. */
 #define INTR_CNT 256
@@ -33,6 +35,9 @@ static intr_handler_func *intr_handlers[INTR_CNT];
 /* Names for each interrupt, for debugging purposes. */
 static const char *intr_names[INTR_CNT];
 
+/* cached values for PIC */
+static uint8_t pic_mask[2];
+
 /* 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
@@ -251,6 +256,8 @@ pic_init (void)
   /* Unmask all interrupts. */
   outb (PIC0_DATA, 0x00);
   outb (PIC1_DATA, 0x00);
+  pic_mask[0] = 0;
+  pic_mask[1] = 0;
 }
 
 /* Sends an end-of-interrupt signal to the PIC for the given IRQ.
@@ -418,3 +425,44 @@ intr_name (uint8_t vec)
 {
   return intr_names[vec];
 }
+
+/** masks a given IRQ */
+void intr_irq_mask(int irq)
+{
+       if(irq < 8){
+               pic_mask[0] |= 1 << irq;
+               outb (PIC0_DATA, pic_mask[0]);
+       }else{  
+               pic_mask[1] |= 1 << (irq - 8);
+               outb (PIC1_DATA, pic_mask[1]);
+       }
+}
+
+/** unmasks a given IRQ */
+void intr_irq_unmask(int irq)
+{
+       if(irq >= 8){
+               /* enable cascade if not enabled for pic2 */
+               if(pic_mask[1] & (1 << (IRQ_CASCADE1 - 8)))
+                       pic_mask[1] &= ~(1 << (IRQ_CASCADE1 - 8));
+
+               pic_mask[1] &= ~(1 << (irq - 8));
+               outb(PIC1_DATA, pic_mask[1]);
+
+               /* enable cascade if not enabled for pic1 */
+               if(pic_mask[0] & (1 << IRQ_CASCADE0))
+                       irq = IRQ_CASCADE0;
+       }
+
+       if(irq < 8){
+               pic_mask[0] &= ~(1 << irq);
+               outb (PIC0_DATA, pic_mask[0]);
+       }
+
+}
+
+/* return whether an interrupt vector is registered */
+bool intr_is_registered(uint8_t vec_no)
+{
+       return (intr_handlers[vec_no] != NULL);
+}