pic.c (1512B)
1 #include "pic.h" 2 #include "idt.h" 3 #include "io.h" 4 5 /* 6 * BIOS reserves IRQ 0 to 15 for the PIC. We need to remap it to non-reserved 7 * vectors so that there are no conflicts when setting our IRQs. 8 */ 9 void 10 pic_remap(void) 11 { 12 u_int8_t m1, m2; 13 14 /* Save masks */ 15 m1 = inb(PIC_MASTER_DATA); 16 m2 = inb(PIC_SLAVE_DATA); 17 18 /* Reinit both PICs */ 19 outb(PIC_MASTER_CMD, ICW1_INIT | ICW1_ICW4); 20 /* Older machines need some time... */ 21 io_wait(); 22 outb(PIC_SLAVE_CMD, ICW1_INIT | ICW1_ICW4); 23 io_wait(); 24 /* Change offsets */ 25 outb(PIC_MASTER_DATA, PIC_MASTER_OFFT); 26 io_wait(); 27 outb(PIC_SLAVE_DATA, PIC_SLAVE_OFFT); 28 io_wait(); 29 /* Slave PIC at IRQ2 */ 30 outb(PIC_MASTER_DATA, 0x04); 31 io_wait(); 32 /* Tell Slave PIC its cascade identity */ 33 outb(PIC_SLAVE_DATA, ICW1_SINGLE); 34 io_wait(); 35 /* 8086 mode */ 36 outb(PIC_MASTER_DATA, ICW4_8086); 37 io_wait(); 38 outb(PIC_SLAVE_DATA, ICW4_8086); 39 io_wait(); 40 /* Restore masks */ 41 outb(PIC_MASTER_DATA, m1); 42 outb(PIC_SLAVE_DATA, m2); 43 } 44 45 void 46 pic_eoi(u_int32_t intrno) 47 { 48 outb(PIC_MASTER_CMD, PIC_EOI); 49 if (intrno >= IRQ8) 50 outb(PIC_SLAVE_CMD, PIC_EOI); 51 } 52 53 void 54 pic_mask(u_int8_t irq, int flag) 55 { 56 u_int16_t port; 57 u_int8_t v; 58 59 if (irq < 8) 60 port = PIC_MASTER_DATA; 61 else { 62 port = PIC_SLAVE_DATA; 63 irq -= 8; 64 } 65 if (flag == PIC_SET_MASK) 66 v = inb(port) | (1 << irq); 67 else if (flag == PIC_CLEAR_MASK) 68 v = inb(port) & ~(1 << irq); 69 else 70 return; 71 outb(port, v); 72 } 73 74 void 75 pic_on(void) 76 { 77 } 78 79 void 80 pic_off(void) 81 { 82 outb(PIC_MASTER_DATA, 0xff); 83 outb(PIC_SLAVE_DATA, 0xff); 84 }