idt.c (5663B)
1 #include <libc.h> 2 #include "libk.h" 3 #include "idt.h" 4 #include "pic.h" 5 #include "cpufunc.h" 6 7 static void idt_set_gate(struct gate_desc *, void *, u_int, u_int, u_int); 8 9 static struct gate_desc idt[NINT]; 10 static intrhand_t isr[NINT] = { NULL }; 11 12 static void 13 idt_set_gate(struct gate_desc *gd, void *func, u_int sel, u_int dpl, u_int type) 14 { 15 u_int32_t addr; 16 17 addr = (u_int32_t)func; 18 gd->gd_hi = (addr & 0xffff0000) | SEGP | dpl | type; 19 gd->gd_lo = (sel << 16) | (addr & 0xffff); 20 } 21 22 /* 23 * u_char so `-pedantic` won't complain about taking the address of `void`. 24 */ 25 extern u_char INTVEC(div), INTVEC(dbg), INTVEC(nmsk), INTVEC(bpt), INTVEC(ofl), 26 INTVEC(bnd), INTVEC(ill), INTVEC(dna), INTVEC(dbl), INTVEC(fpusegm), 27 INTVEC(tss), INTVEC(missing), INTVEC(stk), INTVEC(prot), INTVEC(page), 28 INTVEC(rsvd), INTVEC(fpu), INTVEC(align), INTVEC(mchk), INTVEC(simd); 29 30 extern u_char INTVEC(irq0), INTVEC(irq1), INTVEC(irq2), INTVEC(irq3), 31 INTVEC(irq4), INTVEC(irq5), INTVEC(irq6), INTVEC(irq7), INTVEC(irq8), 32 INTVEC(irq9), INTVEC(irq10), INTVEC(irq11), INTVEC(irq12), INTVEC(irq13), 33 INTVEC(irq14), INTVEC(irq15); 34 35 void 36 idt_init(void) 37 { 38 struct region_desc r_idt; 39 int i; 40 41 for (i = 0; i < NINT; i++) 42 idt_set_gate(&idt[i], &INTVEC(rsvd), KCSEL, SEGPL(KPL), SEGIG); 43 idt_set_gate(&idt[ 0], &INTVEC(div), KCSEL, SEGPL(KPL), SEGIG); 44 idt_set_gate(&idt[ 1], &INTVEC(dbg), KCSEL, SEGPL(KPL), SEGIG); 45 idt_set_gate(&idt[ 2], &INTVEC(nmsk), KCSEL, SEGPL(KPL), SEGIG); 46 idt_set_gate(&idt[ 3], &INTVEC(bpt), KCSEL, SEGPL(KPL), SEGIG); 47 idt_set_gate(&idt[ 4], &INTVEC(ofl), KCSEL, SEGPL(KPL), SEGIG); 48 idt_set_gate(&idt[ 5], &INTVEC(bnd), KCSEL, SEGPL(KPL), SEGIG); 49 idt_set_gate(&idt[ 6], &INTVEC(ill), KCSEL, SEGPL(KPL), SEGIG); 50 idt_set_gate(&idt[ 7], &INTVEC(dna), KCSEL, SEGPL(KPL), SEGIG); 51 idt_set_gate(&idt[ 8], &INTVEC(dbl), KCSEL, SEGPL(KPL), SEGIG); 52 idt_set_gate(&idt[ 9], &INTVEC(fpusegm), KCSEL, SEGPL(KPL), SEGIG); 53 idt_set_gate(&idt[10], &INTVEC(tss), KCSEL, SEGPL(KPL), SEGIG); 54 idt_set_gate(&idt[11], &INTVEC(missing), KCSEL, SEGPL(KPL), SEGIG); 55 idt_set_gate(&idt[12], &INTVEC(stk), KCSEL, SEGPL(KPL), SEGIG); 56 idt_set_gate(&idt[13], &INTVEC(prot), KCSEL, SEGPL(KPL), SEGIG); 57 idt_set_gate(&idt[14], &INTVEC(page), KCSEL, SEGPL(KPL), SEGIG); 58 idt_set_gate(&idt[15], &INTVEC(rsvd), KCSEL, SEGPL(KPL), SEGIG); 59 idt_set_gate(&idt[16], &INTVEC(fpu), KCSEL, SEGPL(KPL), SEGIG); 60 idt_set_gate(&idt[17], &INTVEC(align), KCSEL, SEGPL(KPL), SEGIG); 61 idt_set_gate(&idt[18], &INTVEC(mchk), KCSEL, SEGPL(KPL), SEGIG); 62 idt_set_gate(&idt[19], &INTVEC(simd), KCSEL, SEGPL(KPL), SEGIG); 63 /* 20 - 31 are reserved. */ 64 65 pic_remap(); 66 67 idt_set_gate(&idt[32], &INTVEC(irq0), KCSEL, SEGPL(KPL), SEGIG); 68 idt_set_gate(&idt[33], &INTVEC(irq1), KCSEL, SEGPL(KPL), SEGIG); 69 idt_set_gate(&idt[34], &INTVEC(irq2), KCSEL, SEGPL(KPL), SEGIG); 70 idt_set_gate(&idt[35], &INTVEC(irq3), KCSEL, SEGPL(KPL), SEGIG); 71 idt_set_gate(&idt[36], &INTVEC(irq4), KCSEL, SEGPL(KPL), SEGIG); 72 idt_set_gate(&idt[37], &INTVEC(irq5), KCSEL, SEGPL(KPL), SEGIG); 73 idt_set_gate(&idt[38], &INTVEC(irq6), KCSEL, SEGPL(KPL), SEGIG); 74 idt_set_gate(&idt[39], &INTVEC(irq7), KCSEL, SEGPL(KPL), SEGIG); 75 idt_set_gate(&idt[40], &INTVEC(irq8), KCSEL, SEGPL(KPL), SEGIG); 76 idt_set_gate(&idt[41], &INTVEC(irq9), KCSEL, SEGPL(KPL), SEGIG); 77 idt_set_gate(&idt[42], &INTVEC(irq10), KCSEL, SEGPL(KPL), SEGIG); 78 idt_set_gate(&idt[43], &INTVEC(irq11), KCSEL, SEGPL(KPL), SEGIG); 79 idt_set_gate(&idt[44], &INTVEC(irq12), KCSEL, SEGPL(KPL), SEGIG); 80 idt_set_gate(&idt[45], &INTVEC(irq13), KCSEL, SEGPL(KPL), SEGIG); 81 idt_set_gate(&idt[46], &INTVEC(irq14), KCSEL, SEGPL(KPL), SEGIG); 82 idt_set_gate(&idt[47], &INTVEC(irq15), KCSEL, SEGPL(KPL), SEGIG); 83 84 /*idt_set_gate(&idt[127], &syscall, KCSEL, SEGPL(UPL), SEGIG);*/ 85 86 r_idt.rd_base = (u_int32_t)&idt; 87 r_idt.rd_limit = NINT * sizeof(struct gate_desc) - 1; 88 __asm__ __volatile("lidt (%0)" : : "r" (&r_idt)); 89 } 90 91 static const char *exceptmsg[32] = { 92 "division by zero", 93 "debug exception", 94 "non maskable interrupt", 95 "breakpoint", 96 "overflow", 97 "out of bounds", 98 "invalid opcode", 99 "no coprocessor", 100 "double fault", 101 "coprocessor segment overrun", 102 "bad tss", 103 "segment not present", 104 "stack fault", 105 "general protection fault", 106 "page fault", 107 "15 (reserved)", 108 "coprocessor fault", 109 "alignment check exception (486+)", 110 "machine check exception (pentium/586+)", 111 "simd error", 112 "20 (reserved)", 113 "21 (reserved)", 114 "22 (reserved)", 115 "23 (reserved)", 116 "24 (reserved)", 117 "25 (reserved)", 118 "26 (reserved)", 119 "27 (reserved)", 120 "28 (reserved)", 121 "29 (reserved)", 122 "30 (reserved)", 123 "31 (reserved)", 124 }; 125 126 void 127 intr_handler(struct regs *r) 128 { 129 intrhand_t handler; 130 131 if ((handler = isr[r->r_intrno]) != NULL) 132 handler(r); 133 else if (r->r_intrno < ARRLEN(exceptmsg)) { 134 dump_regs(r); 135 panic("%s: system halted\n", exceptmsg[r->r_intrno]); 136 } 137 pic_eoi(r->r_intrno); 138 } 139 140 void 141 intr_register_handler(int intrno, intrhand_t handler) 142 { 143 if (intrno < 0 || intrno >= NINT) 144 panic("invalid interrupt number: %d\n", intrno); 145 isr[intrno] = handler; 146 pic_mask(intrno, PIC_CLEAR_MASK); 147 } 148 149 void 150 dump_regs(struct regs *r) 151 { 152 printf("eax=%#08x\tebx=%#08x\tecx=%#08x\tedx=%#08x\n", 153 r->r_eax, r->r_ebx, r->r_ecx, r->r_edx); 154 printf("esi=%#08x\tedi=%#08x\tebp=%#08x\tesp=%#08x\n", 155 r->r_esi, r->r_edi, r->r_ebp, r->r_esp); 156 printf("ds=%#04x \t\tes=%#04x \t\tfs=%#04x \t\tgs=%#04x\n", 157 (u_short)r->r_ds, (u_short)r->r_es, (u_short)r->r_fs, (u_short)r->r_gs); 158 printf("cs=%#04x \t\tss=%#04x \t\teip=%#08x\teflags=%#08x\n", 159 (u_short)r->r_cs, (u_short)r->r_ss, r->r_eip, r->r_eflags); 160 printf("int=%#08x\terr=%#08x\tuesp=%#08x\n", 161 r->r_intrno, r->r_err, r->r_uesp); 162 }