selectors, descriptors, more interrupt init
[3sys] / sys1 / kern / src / intr.c
index 5ce0009..dbd8faa 100644 (file)
@@ -1,17 +1,84 @@
+#include <stdio.h>
 #include "intr.h"
 #include "desc.h"
+#include "mem.h"
 
 void set_idt(void *ptr, uint16_t lim);
 
 #define NUM_INTR       256
 static struct desc idt[NUM_INTR] __attribute__((aligned(8)));
+static void (*intr_func[NUM_INTR])();
+
+static struct {
+       char *name;
+       int num;
+       void (*entry)();
+} intrtab[] = {
+       {"divide error", 0, intr_entry_div},
+       {"debug exception", 1, intr_entry_debug},
+       {"non-maskable interrupt", 2, intr_entry_nmi},
+       {"breakpoint", 3, intr_entry_bpt},
+       {"overflow", 4, intr_entry_ovf},
+       {"bounds check", 5, intr_entry_bound},
+       {"invalid opcode", 6, intr_entry_ill},
+       {"missing coprocessor", 7, intr_entry_nodev},
+       {"double fault", 8, intr_entry_dbl},
+       {"coprocessor segment overrun", 9, intr_entry_copseg},
+       {"invalid TSS", 10, intr_entry_tss},
+       {"segment not present", 11, intr_entry_segpres},
+       {"stack exception", 12, intr_entry_stack},
+       {"general protection", 13, intr_entry_prot},
+       {"page fault", 14, intr_entry_page},
+       {"floating point error", 16, intr_entry_fpu},
+       {"alignment check", 17, intr_entry_align},
+       {"machine check", 18, intr_entry_mce},
+       {"SIMD floating point error", 19, intr_entry_sse},
+       {"IRQ 0 (timer)", 32, intr_entry_irq0},
+       {"IRQ 1 (keyboard)", 33, intr_entry_irq1},
+       {"IRQ 2 (cascade)", 34, intr_entry_irq2},
+       {"IRQ 3 (UART 1)", 35, intr_entry_irq3},
+       {"IRQ 4 (UART 0)", 36, intr_entry_irq4},
+       {"IRQ 5", 37, intr_entry_irq5},
+       {"IRQ 6 (floppy)", 38, intr_entry_irq6},
+       {"IRQ 7 (parallel)", 39, intr_entry_irq7_verify},
+       {"IRQ 8 (RTC)", 40, intr_entry_irq8},
+       {"IRQ 9", 41, intr_entry_irq9},
+       {"IRQ 10", 42, intr_entry_irq10},
+       {"IRQ 11", 43, intr_entry_irq11},
+       {"IRQ 12 (PS/2 mouse)", 44, intr_entry_irq12},
+       {"IRQ 13 (coproc)", 45, intr_entry_irq13},
+       {"IRQ 14 (ATA 0)", 46, intr_entry_irq14},
+       {"IRQ 15 (ATA 1)", 47, intr_entry_irq15_verify}
+};
 
 void intr_init(void)
 {
+       int i, inum, type;
+       uint16_t sel_kcode = selector(SEL_KCODE, 0);
+
+       prog_pic(IRQ_OFFS);
+
+       for(i=0; i<256; i++) {
+               type = i < 32 ? GATE_TRAP : GATE_INTR;
+               desc_intr(idt + i, type, sel_kcode, (uint32_t)intr_entry_default, 0);
+       }
+       for(i=0; i<sizeof intrtab / sizeof *intrtab; i++) {
+               inum = intrtab[i].num;
+               type = inum < 32 ? GATE_TRAP : GATE_INTR;
+               desc_intr(idt + inum, type, sel_kcode, (uint32_t)intrtab[i].entry, 0);
+       }
        set_idt(idt, sizeof idt - 1);
 }
 
 void intr_handler(int err, int num)
 {
-}
+       if(intr_func[num]) {
+               intr_func[num]();
+       } else {
+               printf("unhandled interrupt: %d\n", num);
+       }
 
+       if(num >= IRQ_OFFS) {
+               end_of_irq(num - IRQ_OFFS);
+       }
+}