view cos/kernel/handlers.c @ 32:3a6a9b929db0

Added initial ramdisk and some virtual file system functions
author windel
date Fri, 13 Jan 2012 18:18:17 +0100
parents 88590c42320f
children d8185ddb6c7b
line wrap: on
line source

#include "kernel.h"

// Assembler wrapper prototypes:
void INT255(void);
void INT0(void);
void INT1(void);
void INT2(void);
void INT3(void);
void INT4(void);
void INT5(void);
void INT6(void);
void INT7(void);
void INT8(void);
void INT9(void);
void INT10(void);
void INT11(void);
void INT12(void);
void INT13(void);
void INT14(void);
void INT16(void);
void INT17(void);
void INT18(void);
void INT19(void);
// Remapped handlers:
void INT32(void);
void INT33(void);
void INT34(void);

// THE interrupt descriptor table:
IDT_entry *idt = (IDT_entry*)0x5000;
volatile idtPointer idtP;

void setIDTentry(int num, void (*handler)(), uint16_t selector, uint8_t flags)
{
  // Fill one entry with IDT info:
  uint64_t offset;

  // Typecast the function pointer to a number:
  offset = (uint64_t)handler;

  // Set offset:
  idt[num].baseLow = offset & 0xFFFF;
  idt[num].baseMid = (offset >> 16) & 0xFFFF;
  idt[num].baseHigh = (offset >> 32) & 0xFFFFFFFF;

  // Set flags and selector:
  idt[num].selector = selector;
  idt[num].flags = flags;

  // Set reserved fields:
  idt[num].reserved1 = 0;
  idt[num].reserved2 = 0;
}

void setupIDT(void) {
  int i;

  // Fill all vectors with the default handler:
  for (i=0; i<256; i++) {
    setIDTentry(i, INT255, 0x08, 0x8E);
  }

  // Now set other then default handler:
  setIDTentry(0, INT0, 0x08, 0x8E);
  setIDTentry(1, INT1, 0x08, 0x8E);
  setIDTentry(2, INT2, 0x08, 0x8E);
  setIDTentry(3, INT3, 0x08, 0x8E);
  setIDTentry(4, INT4, 0x08, 0x8E);
  setIDTentry(5, INT5, 0x08, 0x8E);
  setIDTentry(6, INT6, 0x08, 0x8E);
  setIDTentry(7, INT7, 0x08, 0x8E);
  setIDTentry(8, INT8, 0x08, 0x8E);
  setIDTentry(9, INT9, 0x08, 0x8E);
  setIDTentry(10, INT10, 0x08, 0x8E);
  setIDTentry(11, INT11, 0x08, 0x8E);
  setIDTentry(12, INT12, 0x08, 0x8E);
  setIDTentry(13, INT13, 0x08, 0x8E);
  setIDTentry(14, INT14, 0x08, 0x8E);
  //setIDTentry(15, INT15, 0x08, 0x8E);
  setIDTentry(16, INT16, 0x08, 0x8E);
  setIDTentry(17, INT17, 0x08, 0x8E);
  setIDTentry(18, INT18, 0x08, 0x8E);
  setIDTentry(19, INT19, 0x08, 0x8E);
  /* reserved interrupts: */
  // From int20 - int31
  setIDTentry(32, INT32, 0x08, 0x8F);
  setIDTentry(33, INT33, 0x08, 0x8F);
  setIDTentry(34, INT34, 0x08, 0x8F);

  // Set the correct values in the IDT pointer:
  idtP.base = (uint64_t)idt;
  idtP.limit = (sizeof(IDT_entry) * 256) - 1;
  // call load IDT asm function:
  loadIDT();

  PICremap();
  asm("sti");
}

// PIC functions:
void PICremap() {
  unsigned char maskmaster, maskslave, pic1, pic2;
  pic1 = 0x20; // remapping location master
  pic2 = 0x28;
  maskmaster = inb(0x21); // master cmd=0x20, data=0x21
  maskslave = inb(0xA1); // slave command=0xA0, data=0xA1

  outb(0x20, 0x20); // end of init

  outb(0x20, 0x11); // init + ICW1_ICW2
  outb(0xA0, 0x11); // init + ICW1_ICW2
    
  outb(0x21, pic1); // ICW2, write offset
  outb(0xA1, pic2); // ICW2

  outb(0x21, 4); // ICW3, write a 4!
  outb(0xA1, 2); // ICW3, write a 2!

  outb(0x21, 1); // ICW4, 8086 mode
  outb(0xA1, 1); // ICW4

  outb(0x21, maskmaster);
  outb(0xA1, maskslave);
}

// Global isr handler:

// Hopefully, this function get called with the correct registers.
void isr_handler(uint64_t* registers)
{
   uint64_t intnum = registers[7];

   // TODO: make a list with handler pointers:
   if (intnum == 32)
   {
      timerDriverUpdate();
   }
   else if (intnum == 33)
   {
      keyboardDriverUpdate();
   }
   else
   {
      // printf("Interrupt %d called, registers at: %x\n", registers[7], registers);
   }

   // TODO: EOI to slave?
   // TODO: replace this with APIC code?
   outb(0x20, 0x20); // EOI to master
}

// Interrupt service routines:

void INT14handler()
{
  uint64_t faulting_address;

  printf("Segfault!\n");

  // Retrieve failed page from CR2:
  asm volatile("mov %%cr2, %0" : "=r" (faulting_address));

  printf("INT14 called! Page fault for address 0x%X!\n", faulting_address);

  panic("Unhandled exception!");
}

void INT15handler() 
{
  printf("INT15 called!\n");
  panic("Unhandled exception!");
}

void INTDEF_handler() 
{
  panic("Default int handler called\n");
}