#include #include "kernel.h" #include "ioport.h" #include "pic.h" #include "interrupt.h" /* ioports */ #define MCMD 0x20 #define SCMD 0xA0 #define MDATA 0x21 #define SDATA 0xA1 #define IRR 0x0A #define ISR 0x0B #define EOI 0x20 #define ICW1_ICW4 0x01 #define CMD_INIT 0x10 #define MODE_8086 0x01 static uint16_t readregister(uint8_t ocw3) { outport8(MCMD, ocw3); outport8(SCMD, ocw3); return inport8(MCMD) | inport8(SCMD) << 8; } static uint16_t readirr() { return readregister(IRR); } static uint16_t readisr() { return readregister(ISR); } static void reprogram() { outport8(MCMD, CMD_INIT | ICW1_ICW4); outport8(SCMD, CMD_INIT | ICW1_ICW4); outport8(MDATA, IRQ0); outport8(SDATA, IRQ8); outport8(MDATA, 0x04); /* Slave PIC at IRQ2 */ outport8(SDATA, 0x02); /* Cascade Identity */ outport8(MDATA, MODE_8086); outport8(SDATA, MODE_8086); /* masks */ outport8(MDATA, 0); outport8(SDATA, 0); } static void deprogram() { outport8(MCMD, CMD_INIT | ICW1_ICW4); outport8(SCMD, CMD_INIT | ICW1_ICW4); outport8(MDATA, 0x08); outport8(SDATA, 0x70); outport8(MDATA, 0x04); /* Slave PIC at IRQ2 */ outport8(SDATA, 0x02); /* Cascade Identity */ outport8(MDATA, MODE_8086); outport8(SDATA, MODE_8086); outport8(MDATA, 0); outport8(SDATA, 0); } static void sendmastereoi() { outport8(MCMD, EOI); } static void sendslaveeoi() { outport8(SCMD, EOI); } static void sendeoi(unsigned int irq) { if (irq >= 8) { sendslaveeoi(); } sendmastereoi(); } struct pic pic; void pic_init() { pic.eoi = sendeoi; pic.mastereoi = sendmastereoi; pic.readirr = readirr; pic.readisr = readisr; pic.reprogram = reprogram; pic.deprogram = deprogram; }