#include "pic.h" #include "io.h" #include "irq.h" #define ICW1_ICW4 0x01 /* ICW4 (not) needed */ #define ICW1_SINGLE 0x02 /* Single (cascade) mode */ #define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */ #define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */ #define ICW1_INIT 0x10 /* Initialization - required! */ #define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */ #define ICW4_AUTO 0x02 /* Auto (normal) EOI */ #define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */ #define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */ #define ICW4_SFNM 0x10 /* Special fully nested (not) */ void initPic(void) { /* Send CMD: Init + sequence in 4 DATA */ outb(PIC_MASTER_CMD, ICW1_INIT + ICW1_ICW4); outb(PIC_SLAVE_CMD, ICW1_INIT + ICW1_ICW4); /* Send ICW2: ctrl base address. Remap IRQ from interupt range 0x0-0xF to 0x20-0x2F as * intel * reserve interupt 0x0-0x1F in protected mode (e.g. 0-7 are CPU exception) */ outb(PIC_MASTER_DATA, IRQ_INTERRUPT_BASE_ADDRESS); outb(PIC_SLAVE_DATA, IRQ_INTERRUPT_BASE_ADDRESS + 8); /* Send ICW3 master: mask where slaves are connected */ outb(PIC_MASTER_DATA, 0x4); /* Send ICW3 slave: index where the slave is connected on master */ outb(PIC_SLAVE_DATA, 0x2); /* Send ICW4: 8086 mode, fully nested, not buffered, no implicit EOI */ outb(PIC_MASTER_DATA, ICW4_8086); outb(PIC_SLAVE_DATA, ICW4_8086); /* Send OCW1: * Closing all IRQs : waiting for a correct handler The only IRQ * enabled is the cascade (that's why we use 0xFB for the master) */ outb(PIC_MASTER_DATA, 0xFB); outb(PIC_SLAVE_DATA, 0xFF); } void EOIIrq(int irq) { if (irq >= 8) outb(PIC_SLAVE_CMD, PIC_EOI); outb(PIC_MASTER_CMD, PIC_EOI); } void disableIrq(int irq) { if (irq < 8) { uint8_t status = inb(PIC_MASTER_DATA); outb(PIC_MASTER_DATA, (status | (1 << irq))); } else { uint8_t status = inb(PIC_SLAVE_DATA); outb(PIC_SLAVE_DATA, (status | (1 << (irq - 8)))); } } void enableIrq(int irq) { if (irq < 8) { uint8_t status = inb(PIC_MASTER_DATA); outb(PIC_MASTER_DATA, (status & ~(1 << irq))); } else { uint8_t status = inb(PIC_SLAVE_DATA); outb(PIC_SLAVE_DATA, (status & ~(1 << (irq - 8)))); } }