foo
[eightysix] / kern / src / intr.c
diff --git a/kern/src/intr.c b/kern/src/intr.c
new file mode 100644 (file)
index 0000000..e682b30
--- /dev/null
@@ -0,0 +1,109 @@
+#include "intr.h"
+
+/* PIC command and data ports */
+#define PIC1_CMD       0x20
+#define PIC1_DATA      0x21
+#define PIC2_CMD       0xa0
+#define PIC2_DATA      0xa1
+
+/* PIC initialization command word 1 bits */
+#define ICW1_ICW4_NEEDED       (1 << 0)
+#define ICW1_SINGLE                    (1 << 1)
+#define ICW1_INTERVAL4         (1 << 2)
+#define ICW1_LEVEL                     (1 << 3)
+#define ICW1_INIT                      (1 << 4)
+/* PIC initialization command word 4 bits */
+#define ICW4_8086                      (1 << 0)
+#define ICW4_AUTO_EOI          (1 << 1)
+#define ICW4_BUF_SLAVE         (1 << 3) /* 1000 */
+#define ICW4_BUF_MASTER                (3 << 2) /* 1100 */
+#define ICW4_SPECIAL           (1 << 4)
+/* PIC operation command word 2 bits */
+#define OCW2_EOI       (1 << 5)
+
+
+#define MAX_INTR       32
+static intr_func_t intrfunc[MAX_INTR];
+
+static void (*intr_unhandled)(struct intr_frame *frm);
+
+void intr_entry_div();
+void intr_entry_trap();
+void intr_entry_nmi();
+void intr_entry_break();
+void intr_entry_ovf();
+void intr_entry_bound();
+void intr_entry_ill();
+void intr_entry_irq0();
+void intr_entry_irq1();
+void intr_entry_irq2();
+void intr_entry_irq3();
+void intr_entry_irq4();
+void intr_entry_irq5();
+void intr_entry_irq6();
+void intr_entry_irq7();
+
+extern int _kern_start_seg;
+#define KERN_CS        ((uint16_t)(&_kern_start_seg))
+
+
+void init_intr(void)
+{
+       int i;
+
+       for(i=0; i<MAX_INTR; i++) {
+               intrfunc[i] = 0;
+       }
+
+       set_intr_vect(0, KERN_CS, (uint16_t)intr_entry_div);
+}
+
+void dispatch_intr(struct intr_frame frm)
+{
+       intrfunc[frm.inum](&frm);
+}
+
+void set_intr_vect(int n, uint16_t seg, uint16_t offs)
+{
+       uint16_t *ivt = 0;
+
+       ivt[n * 4] = offs;
+       ivt[n * 4 + 1] = seg;
+}
+
+void set_intr(int n, intr_func_t func)
+{
+       intrfunc[n] = func;
+}
+
+void mask_irq(int n)
+{
+       int port;
+       unsigned char mask;
+
+       if(n < 8) {
+               port = PIC1_DATA;
+       } else {
+               port = PIC2_DATA;
+               n -= 8;
+       }
+
+       mask = inp(port) | (1 << n);
+       outp(port, mask);
+}
+
+void unmask_irq(int n)
+{
+       int port;
+       unsigned char mask;
+
+       if(n < 8) {
+               port = PIC1_DATA;
+       } else {
+               port = PIC2_DATA;
+               n -= 8;
+       }
+
+       mask = inp(port) & ~(1 << n);
+       outp(port, mask);
+}