selectors, descriptors, more interrupt init
[3sys] / sys1 / kern / src / intr.c
1 #include <stdio.h>
2 #include "intr.h"
3 #include "desc.h"
4 #include "mem.h"
5
6 void set_idt(void *ptr, uint16_t lim);
7
8 #define NUM_INTR        256
9 static struct desc idt[NUM_INTR] __attribute__((aligned(8)));
10 static void (*intr_func[NUM_INTR])();
11
12 static struct {
13         char *name;
14         int num;
15         void (*entry)();
16 } intrtab[] = {
17         {"divide error", 0, intr_entry_div},
18         {"debug exception", 1, intr_entry_debug},
19         {"non-maskable interrupt", 2, intr_entry_nmi},
20         {"breakpoint", 3, intr_entry_bpt},
21         {"overflow", 4, intr_entry_ovf},
22         {"bounds check", 5, intr_entry_bound},
23         {"invalid opcode", 6, intr_entry_ill},
24         {"missing coprocessor", 7, intr_entry_nodev},
25         {"double fault", 8, intr_entry_dbl},
26         {"coprocessor segment overrun", 9, intr_entry_copseg},
27         {"invalid TSS", 10, intr_entry_tss},
28         {"segment not present", 11, intr_entry_segpres},
29         {"stack exception", 12, intr_entry_stack},
30         {"general protection", 13, intr_entry_prot},
31         {"page fault", 14, intr_entry_page},
32         {"floating point error", 16, intr_entry_fpu},
33         {"alignment check", 17, intr_entry_align},
34         {"machine check", 18, intr_entry_mce},
35         {"SIMD floating point error", 19, intr_entry_sse},
36         {"IRQ 0 (timer)", 32, intr_entry_irq0},
37         {"IRQ 1 (keyboard)", 33, intr_entry_irq1},
38         {"IRQ 2 (cascade)", 34, intr_entry_irq2},
39         {"IRQ 3 (UART 1)", 35, intr_entry_irq3},
40         {"IRQ 4 (UART 0)", 36, intr_entry_irq4},
41         {"IRQ 5", 37, intr_entry_irq5},
42         {"IRQ 6 (floppy)", 38, intr_entry_irq6},
43         {"IRQ 7 (parallel)", 39, intr_entry_irq7_verify},
44         {"IRQ 8 (RTC)", 40, intr_entry_irq8},
45         {"IRQ 9", 41, intr_entry_irq9},
46         {"IRQ 10", 42, intr_entry_irq10},
47         {"IRQ 11", 43, intr_entry_irq11},
48         {"IRQ 12 (PS/2 mouse)", 44, intr_entry_irq12},
49         {"IRQ 13 (coproc)", 45, intr_entry_irq13},
50         {"IRQ 14 (ATA 0)", 46, intr_entry_irq14},
51         {"IRQ 15 (ATA 1)", 47, intr_entry_irq15_verify}
52 };
53
54 void intr_init(void)
55 {
56         int i, inum, type;
57         uint16_t sel_kcode = selector(SEL_KCODE, 0);
58
59         prog_pic(IRQ_OFFS);
60
61         for(i=0; i<256; i++) {
62                 type = i < 32 ? GATE_TRAP : GATE_INTR;
63                 desc_intr(idt + i, type, sel_kcode, (uint32_t)intr_entry_default, 0);
64         }
65         for(i=0; i<sizeof intrtab / sizeof *intrtab; i++) {
66                 inum = intrtab[i].num;
67                 type = inum < 32 ? GATE_TRAP : GATE_INTR;
68                 desc_intr(idt + inum, type, sel_kcode, (uint32_t)intrtab[i].entry, 0);
69         }
70         set_idt(idt, sizeof idt - 1);
71 }
72
73 void intr_handler(int err, int num)
74 {
75         if(intr_func[num]) {
76                 intr_func[num]();
77         } else {
78                 printf("unhandled interrupt: %d\n", num);
79         }
80
81         if(num >= IRQ_OFFS) {
82                 end_of_irq(num - IRQ_OFFS);
83         }
84 }