/**************************************************************************************
Copyright (c) 2002
The UbixOS Project
$Id$
**************************************************************************************/
#include <ubixos/idt.h>
#include <ubixos/gdt.h>
#include <ubixos/schedule.h>
#include <ubixos/syscall.h>
#include <drivers/video.h>
descriptorTable(IDT, 256) {
};
struct {
unsigned short limit __attribute__ ((packed));
union descriptorTableunion *idt __attribute__ ((packed));
} loadidt= { (256 * sizeof(union descriptorTableunion) - 1), IDT };
/* Sets Up Initial IDT Table */
void initIdt() {
int i=0;
for (i=0;i<256;i++) {
setVector(intNull, i, dPresent + dInt + dDpl3);
}
asm (
"lidt (%0) \n" /* Load the IDT */
"pushfl \n" /* Clear the NT flag */
"andl $0xffffbfff,(%%esp) \n"
"popfl \n"
"sti \n"
:
: "r" ((char *) &loadidt)
);
setVector(_int0,0,dPresent + dInt + dDpl3);
setVector(_int1,1,dPresent + dInt + dDpl3);
setVector(_int2,2,dPresent + dInt + dDpl3);
setVector(_int3,3,dPresent + dInt + dDpl3);
setVector(_int4,4,dPresent + dInt + dDpl3);
setVector(_int5,5,dPresent + dInt + dDpl3);
setVector(_int6,6,dPresent + dInt + dDpl3);
setVector(_sysCall,128,dPresent + dInt + dDpl3);
}
/* Sets Up IDT Vector */
void setVector(void *handler, unsigned char interrupt, unsigned short controlMajor) {
unsigned short codesegment = 0x08;
asm volatile("movw %%cs,%0":"=g" (codesegment));
IDT[interrupt].gate.offsetLow = (unsigned short) (((unsigned long)handler)&0xffff);
IDT[interrupt].gate.selector = codesegment;
IDT[interrupt].gate.access = controlMajor;
IDT[interrupt].gate.offsetHigh = (unsigned short) (((unsigned long)handler) >> 16);
}
/* Null Intterupt Descriptor */
void intNull() {
kprintf("Woot Invalid Interrupt\n");
while(1);
}
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() {
kprintf("int6: Invalid opcode!\n");
_current->status = AVAILABLE;
schedule();
while(1);
}