Newer
Older
ubixos / src / sys / kernel / idt.c
@reddawg reddawg on 28 May 2002 2 KB Its Been lots of work
/**************************************************************************************
 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);
  }