idt.c (5774B)
1 /* 2 * core/idt.c 3 * 4 * Copyright (C) 2009 stateless 5 */ 6 7 #include <idt.h> 8 #include <common.h> 9 #include <x86.h> 10 #include <string.h> 11 #include <syscall.h> 12 #include <tss.h> 13 #include <errno.h> 14 #include <tty.h> 15 #include <pic.h> 16 17 #define INIT_IDT_INTR_GATE(index, offset, sel, gsize, pl, sp) \ 18 ({ \ 19 idt_intr_gates[index].offset_lo = (uint16_t)offset; \ 20 idt_intr_gates[index].selector = sel; \ 21 idt_intr_gates[index].all0 = 0; \ 22 idt_intr_gates[index].gate_size = gsize; \ 23 idt_intr_gates[index].privilege_level = pl; \ 24 idt_intr_gates[index].segment_present = sp; \ 25 idt_intr_gates[index].offset_hi = (uint16_t)(offset >> 16) & 0xffff; \ 26 }) 27 28 extern void idt_flush(uint32_t); 29 extern void syscall_handler(void); 30 31 static const char *interrupt_names[] = { 32 "Division by zero exception", 33 "Debug exception", 34 "Non maskable interrupt", 35 "Breakpoint exception", 36 "Into detected overflow", 37 "Out of bounds exception", 38 "Invalid opcode exception", 39 "No coprocessor exception", 40 "Double fault", 41 "Coprocessor segment overrun", 42 "Bad TSS", 43 "Segment not present", 44 "Stack fault", 45 "General protection fault", 46 "Page fault", 47 "Unknown interrupt exception", 48 "Coprocessor fault", 49 "Alignment check exception", 50 "Machine check exception" 51 }; 52 53 static isr_handler isr_handlers[256]; 54 static struct idt_intr_gate idt_intr_gates[256]; 55 static struct idt_selector idt_intr_sel; 56 57 static void 58 spurious_irq7(__attribute__ ((unused)) struct trapframe_t *regs) 59 { 60 } 61 62 void 63 initialize_idt(void) 64 { 65 idt_intr_sel.limit = sizeof(struct idt_intr_gate) * 256 - 1; 66 idt_intr_sel.base = (uint32_t)idt_intr_gates; 67 68 memset(idt_intr_gates, 0, sizeof(struct idt_intr_gate) * 256); 69 70 INIT_IDT_INTR_GATE(0, (uint32_t)isr0, 0x08, 0xe, 0x0, 0x1); 71 INIT_IDT_INTR_GATE(1, (uint32_t)isr1, 0x08, 0xe, 0x0, 0x1); 72 INIT_IDT_INTR_GATE(2, (uint32_t)isr2, 0x08, 0xe, 0x0, 0x1); 73 INIT_IDT_INTR_GATE(3, (uint32_t)isr3, 0x08, 0xe, 0x0, 0x1); 74 INIT_IDT_INTR_GATE(4, (uint32_t)isr4, 0x08, 0xe, 0x0, 0x1); 75 INIT_IDT_INTR_GATE(5, (uint32_t)isr5, 0x08, 0xe, 0x0, 0x1); 76 INIT_IDT_INTR_GATE(6, (uint32_t)isr6, 0x08, 0xe, 0x0, 0x1); 77 INIT_IDT_INTR_GATE(7, (uint32_t)isr7, 0x08, 0xe, 0x0, 0x1); 78 INIT_IDT_INTR_GATE(8, (uint32_t)isr8, 0x08, 0xe, 0x0, 0x1); 79 INIT_IDT_INTR_GATE(9, (uint32_t)isr9, 0x08, 0xe, 0x0, 0x1); 80 INIT_IDT_INTR_GATE(10, (uint32_t)isr10, 0x08, 0xe, 0x0, 0x1); 81 INIT_IDT_INTR_GATE(11, (uint32_t)isr11, 0x08, 0xe, 0x0, 0x1); 82 INIT_IDT_INTR_GATE(12, (uint32_t)isr12, 0x08, 0xe, 0x0, 0x1); 83 INIT_IDT_INTR_GATE(13, (uint32_t)isr13, 0x08, 0xe, 0x0, 0x1); 84 INIT_IDT_INTR_GATE(14, (uint32_t)isr14, 0x08, 0xe, 0x0, 0x1); 85 INIT_IDT_INTR_GATE(15, (uint32_t)isr15, 0x08, 0xe, 0x0, 0x1); 86 INIT_IDT_INTR_GATE(16, (uint32_t)isr16, 0x08, 0xe, 0x0, 0x1); 87 INIT_IDT_INTR_GATE(17, (uint32_t)isr17, 0x08, 0xe, 0x0, 0x1); 88 INIT_IDT_INTR_GATE(18, (uint32_t)isr18, 0x08, 0xe, 0x0, 0x1); 89 INIT_IDT_INTR_GATE(19, (uint32_t)isr19, 0x08, 0xe, 0x0, 0x1); 90 INIT_IDT_INTR_GATE(20, (uint32_t)isr20, 0x08, 0xe, 0x0, 0x1); 91 INIT_IDT_INTR_GATE(21, (uint32_t)isr21, 0x08, 0xe, 0x0, 0x1); 92 INIT_IDT_INTR_GATE(22, (uint32_t)isr22, 0x08, 0xe, 0x0, 0x1); 93 INIT_IDT_INTR_GATE(23, (uint32_t)isr23, 0x08, 0xe, 0x0, 0x1); 94 INIT_IDT_INTR_GATE(24, (uint32_t)isr24, 0x08, 0xe, 0x0, 0x1); 95 INIT_IDT_INTR_GATE(25, (uint32_t)isr25, 0x08, 0xe, 0x0, 0x1); 96 INIT_IDT_INTR_GATE(26, (uint32_t)isr26, 0x08, 0xe, 0x0, 0x1); 97 INIT_IDT_INTR_GATE(27, (uint32_t)isr27, 0x08, 0xe, 0x0, 0x1); 98 INIT_IDT_INTR_GATE(28, (uint32_t)isr28, 0x08, 0xe, 0x0, 0x1); 99 INIT_IDT_INTR_GATE(29, (uint32_t)isr29, 0x08, 0xe, 0x0, 0x1); 100 INIT_IDT_INTR_GATE(30, (uint32_t)isr30, 0x08, 0xe, 0x0, 0x1); 101 INIT_IDT_INTR_GATE(31, (uint32_t)isr31, 0x08, 0xe, 0x0, 0x1); 102 INIT_IDT_INTR_GATE(32, (uint32_t)isr32, 0x08, 0xe, 0x0, 0x1); 103 INIT_IDT_INTR_GATE(33, (uint32_t)isr33, 0x08, 0xe, 0x0, 0x1); 104 INIT_IDT_INTR_GATE(34, (uint32_t)isr34, 0x08, 0xe, 0x0, 0x1); 105 INIT_IDT_INTR_GATE(35, (uint32_t)isr35, 0x08, 0xe, 0x0, 0x1); 106 INIT_IDT_INTR_GATE(36, (uint32_t)isr36, 0x08, 0xe, 0x0, 0x1); 107 INIT_IDT_INTR_GATE(37, (uint32_t)isr37, 0x08, 0xe, 0x0, 0x1); 108 INIT_IDT_INTR_GATE(38, (uint32_t)isr38, 0x08, 0xe, 0x0, 0x1); 109 INIT_IDT_INTR_GATE(39, (uint32_t)isr39, 0x08, 0xe, 0x0, 0x1); 110 INIT_IDT_INTR_GATE(40, (uint32_t)isr40, 0x08, 0xe, 0x0, 0x1); 111 INIT_IDT_INTR_GATE(41, (uint32_t)isr41, 0x08, 0xe, 0x0, 0x1); 112 INIT_IDT_INTR_GATE(42, (uint32_t)isr42, 0x08, 0xe, 0x0, 0x1); 113 INIT_IDT_INTR_GATE(43, (uint32_t)isr43, 0x08, 0xe, 0x0, 0x1); 114 INIT_IDT_INTR_GATE(44, (uint32_t)isr44, 0x08, 0xe, 0x0, 0x1); 115 INIT_IDT_INTR_GATE(45, (uint32_t)isr45, 0x08, 0xe, 0x0, 0x1); 116 INIT_IDT_INTR_GATE(46, (uint32_t)isr46, 0x08, 0xe, 0x0, 0x1); 117 INIT_IDT_INTR_GATE(47, (uint32_t)isr47, 0x08, 0xe, 0x0, 0x1); 118 INIT_IDT_INTR_GATE(0x80, (uint32_t)isr128, 0x08, 0xe, 0x0, 0x1); 119 120 register_isr_handler(0x80, syscall_dispatcher); 121 register_isr_handler(39, spurious_irq7); 122 idt_flush((uint32_t)&idt_intr_sel); 123 } 124 125 int 126 register_isr_handler(uint8_t index, isr_handler handler) 127 { 128 if (!handler) 129 return -EINVAL; 130 isr_handlers[index] = handler; 131 return 0; 132 } 133 134 uint32_t 135 handle_interrupt(struct trapframe_t regs) 136 { 137 if (isr_handlers[regs.int_no]) { 138 if (curr_proc) { 139 curr_proc->esp = regs.unroll_esp; 140 if (regs.int_no == 0x80 && regs.eax != __NR_suspend_task) 141 curr_proc->old_esp = curr_proc->esp; 142 curr_proc->cf = (struct cswitch_frame_t *)((uint32_t *) & regs + 1); 143 } 144 isr_handler handler = isr_handlers[regs.int_no]; 145 handler(®s); 146 } else { 147 clear_scr(); 148 ccurr_col(BLACK, RED); 149 DEBUG_CODE(printf("Unhandled interrupt[%lu]: %s\n", regs.int_no, 150 (regs.int_no < (sizeof(interrupt_names) / sizeof(interrupt_names[0]))) 151 ? interrupt_names[regs.int_no] : "Unknown");) 152 DUMP_STACK_REGS(regs); 153 panic("halted"); 154 } 155 pic_eoi(regs.int_no); 156 if (!curr_proc) 157 return regs.unroll_esp; 158 return curr_proc->esp; 159 } 160