X-Git-Url: https://pd.if.org/git/?p=zos;a=blobdiff_plain;f=pic.c;fp=pic.c;h=5e53860bb785649ef84798cde0178176881bbcf3;hp=0000000000000000000000000000000000000000;hb=4bfc87356b0316256d2eaf91497973dbddcd2db7;hpb=a1c6cedc6e0e0de663002e9dd231b8c2309f2544 diff --git a/pic.c b/pic.c new file mode 100644 index 0000000..5e53860 --- /dev/null +++ b/pic.c @@ -0,0 +1,89 @@ +#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; +}