108 lines
3.1 KiB
C
Executable file
108 lines
3.1 KiB
C
Executable file
/*
|
|
File: idt.C
|
|
|
|
Date : 09/03/02
|
|
|
|
*/
|
|
|
|
/* Based largely on
|
|
* bkerndev - Bran's Kernel Development Tutorial
|
|
* By: Brandon F. (friesenb@gmail.com)
|
|
* Desc: Interrupt Descriptor Table management
|
|
*
|
|
* Notes: No warranty expressed or implied. Use at own risk. */
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* DEFINES */
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
/* -- (none) -- */
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* INCLUDES */
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
//#include "assert.H"
|
|
#include "utils.H"
|
|
#include "idt.H"
|
|
#include "console.H"
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* EXTERNS */
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
/* Used to load our IDT, defined in 'idt_low.s' */
|
|
extern "C" void idt_load();
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* DATA STRUCTURES */
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
struct idt_entry
|
|
{
|
|
unsigned short base_lo;
|
|
unsigned short sel;
|
|
unsigned char always0;
|
|
unsigned char flags;
|
|
unsigned short base_hi;
|
|
} __attribute__((packed));
|
|
|
|
struct idt_ptr
|
|
{
|
|
unsigned short limit;
|
|
unsigned int base;
|
|
} __attribute__((packed));
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* VARIABLES */
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
|
|
/* Declare an IDT of IDT_SIZE entries. We use only the first 32
|
|
entries. If any undefined IDT entry is hit, it normally
|
|
cause an "Unhandled Interrupt" exception. Any descriptor
|
|
for which the 'presence' bit is cleared will generate an
|
|
"Unhandled Interrupt" exception. */
|
|
struct idt_entry idt[IDT::SIZE];
|
|
struct idt_ptr idtp;
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* HOOKING UP THE LOW-LEVEL EXCEPTION HANDLER TO EXCEPTIONDISPATCHER. */
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
/* Use this function to set an entry in the IDT. */
|
|
void IDT::set_gate(unsigned char num, unsigned long base,
|
|
unsigned short sel, unsigned char flags) {
|
|
|
|
Console::puts("Installing handler in IDT position ");
|
|
Console::puti((int)num);
|
|
Console::puts("\n");
|
|
|
|
/* The interrupt routine's base address */
|
|
idt[num].base_lo = (base & 0xFFFF);
|
|
idt[num].base_hi = (base >> 16) & 0xFFFF;
|
|
|
|
/* The segment or 'selector' that this IDT entry will use
|
|
* is set here, along with any access flags */
|
|
idt[num].sel = sel;
|
|
idt[num].always0 = 0;
|
|
idt[num].flags = flags;
|
|
|
|
}
|
|
|
|
/* Installs the IDT */
|
|
void IDT::init() {
|
|
|
|
/* Sets the special IDT pointer up. */
|
|
idtp.limit = (sizeof (struct idt_entry) * 256) - 1;
|
|
idtp.base = (unsigned int)&idt;
|
|
|
|
/* Clear out the entire IDT, initializing it to zeros. */
|
|
memset(&idt, 0, sizeof(struct idt_entry) * 256);
|
|
|
|
|
|
/* Points the processor's internal register to the new IDT */
|
|
idt_load();
|
|
}
|