/************************************************************************************** Copyright (c) 2002 The UbixOS Project $Id: idt.c,v 1.17 2002/04/26 22:52:44 reddawg Exp $ **************************************************************************************/ #include <ubixos/io.h> #include <ubixos/schedule.h> #include <ubixos/8259.h> #include <ubixos/gdt.h> #include <ubixos/idt.h> #include <ubixos/video.h> #include <ubixos/sysCall.h> #include <mm/paging.h> extern void int_null(); extern void _int14(); extern void math_emulate(); desc_table(IDT, 256) { }; struct { unsigned short limit __attribute__ ((packed)); union DT_entry *idt __attribute__ ((packed)); } loadidt= { (256 * sizeof(union DT_entry) - 1), IDT }; void init_IDT() { int count=0; for(count = 16; count < 256; count++) { set_vector(int_null, count, D_PRESENT + D_INT + D_DPL3); } set_vector(_int0, 0, D_PRESENT + D_INT + D_DPL3); set_vector(_int1, 1, D_PRESENT + D_INT + D_DPL3); set_vector(_int2, 2, D_PRESENT + D_INT + D_DPL3); set_vector(_int3, 3, D_PRESENT + D_INT + D_DPL3); set_vector(_int4, 4, D_PRESENT + D_INT + D_DPL3); set_vector(_int5, 5, D_PRESENT + D_INT + D_DPL3); set_vector(_int6, 6, D_PRESENT + D_INT + D_DPL3); set_vector(_int7, 7, D_PRESENT + D_INT + D_DPL3); set_vector(_int8, 8, D_PRESENT + D_INT + D_DPL3); set_vector(_int9, 9, D_PRESENT + D_INT + D_DPL3); set_vector(_int10, 10, D_PRESENT + D_INT + D_DPL3); set_vector(_int12, 12, D_PRESENT + D_INT + D_DPL3); set_vector(_int13, 13, D_PRESENT + D_INT + D_DPL3); set_vector(_int14, 14, D_PRESENT + D_INT + D_DPL3); set_vector(_int15, 15, D_PRESENT + D_INT + D_DPL3); set_vector(_int16, 16, D_PRESENT + D_INT + D_DPL3); set_vector(sysCall, 128, D_PRESENT + D_INT + D_DPL3); asm ( "lidt (%0) \n" /* Load the IDT */ "pushfl \n" /* Clear the NT flag */ "andl $0xffffbfff,(%%esp) \n" "popfl \n" : : "r" ((char *) &loadidt) ); asm("sti"); } void set_vector(void *handler, unsigned char interrupt, unsigned short control_major) { unsigned short codesegment = 0x08; asm volatile("movw %%cs,%0":"=g" (codesegment)); IDT[interrupt].gate.offset_low = (unsigned short) (((unsigned long)handler)&0xffff); IDT[interrupt].gate.selector = codesegment; IDT[interrupt].gate.access = control_major; IDT[interrupt].gate.offset_high = (unsigned short) (((unsigned long)handler) >> 16); } asm ( ".globl int_null \n" "int_null: \n" " iret \n" /* Exit interrupt */ ); void _int0() { kprint("int0: Divide-by-Zero\n"); while(1); } void _int1() { kprint("int1: Debug exception\n"); while(1); } void _int2() { kprint("int2: unknown error\n"); while(1); } void _int3() { kprint("int3: Breakpoint\n"); while(1); } void _int4() { kprint("int4: Overflow\n"); while(1); } void _int5() { kprint("int 5: Bounds check\n"); while(1); } void _int6() { printColor = 0x04; kprint("\nint6: Invalid opcode!\n"); while(1); } void mathSwitch() { if (_usedMath) asm("fnsave %0"::"m" (_usedMath->i387)); if (_current->usedMath) asm("frstor %0"::"m" (_current->i387)); else { asm("fninit"::); _current->usedMath=1; } _usedMath=_current; } void _int8() { kprint("int8: Double fault\n"); while(1); } void _int9() { kprint("int9: Coprocessor Segment overrun\n"); while(1); } void _int10() { kprint("int10: Invalid TSS\n"); while(1); } void _int11() { kprint("int11: Segment not present\n"); while(1); } void _int12() { kprint("int12: Stack exception\n"); while(1); } void _int13() { int reg; asm( "movl %%cs,%%eax\n" "movl %%eax,%0\n" : "=g" (reg) ); kprint("["); printlong(reg); kprint("]\n"); kprint("int13: General Protection\n"); while(1); } asm( ".global _int14 \n" "_int14: \n" "xchgl %eax,(%esp) \n" "pushl %ecx \n" "pushl %edx \n" "push %ds \n" "push %es \n" "push %fs \n" "call pageFault \n" "pop %fs \n" "pop %es \n" "pop %ds \n" "popl %edx \n" "popl %ecx \n" "popl %eax \n" "iret \n" ); void _int15() { kprint("in15: Unknown error\n"); while(1); } void _int16() { kprint("int16: Coprocessor error\n"); while(1); } asm( ".globl _int7 \n" "_int7: \n" " clts \n" " call mathSwitch \n" " iret \n" );