]> pd.if.org Git - zos/blobdiff - pic.c
pic reprograming
[zos] / pic.c
diff --git a/pic.c b/pic.c
new file mode 100644 (file)
index 0000000..5e53860
--- /dev/null
+++ b/pic.c
@@ -0,0 +1,89 @@
+#include <stdint.h>
+
+#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;
+}