X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fthreads%2Finterrupt.c;h=27f470861a22de11b725475b731d2a11afdfafcc;hb=b4e9c266d656c6b595cc57920a34937776acc300;hp=9ffd873540b803ca3414b83f10c6da4e8c4b2f54;hpb=6ffbc2b68c34c2d1e42d5f6bcd8f2b94b82d05d7;p=pintos-anon diff --git a/src/threads/interrupt.c b/src/threads/interrupt.c index 9ffd873..27f4708 100644 --- a/src/threads/interrupt.c +++ b/src/threads/interrupt.c @@ -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); +}