cynix

x86 UNIX-like OS
git clone git://git.2f30.org/cynix
Log | Files | Refs | README | LICENSE

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(&regs);
    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