/* Interrupt Descriptor Table */
/* Copyright (C) 2008 Emmanuel Varoquaux
This file is part of XOS.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see . */
/* La IDT provisoire mise en place par le code de demarrage est vide et toute
* exception ou interruption provoque un triple-faute-reboot. Les interruptions
* externes sont cependant masquees pendant l'initialisation du systeme. */
#include
#include
#include
#include
#include
#include
#include
static struct descr_struct idt[256];
/* Descripteurs */
static void set_interrupt_gate(unsigned int index, int dpl, void *handler)
{
struct descr_data_struct ig_dat;
ig_dat.type = 0; /* system */
ig_dat.system_type = SDT_386INTGT; /* interrupt gate */
ig_dat.dpl = dpl;
ig_dat.present = 1;
ig_dat.selector = KERNEL_CODE_SEL;
ig_dat.offset = (unsigned long)handler;
set_descr(&idt[index], &ig_dat);
}
static void set_trap_gate(unsigned int index, int dpl, void *handler)
{
struct descr_data_struct tg_dat;
tg_dat.type = 0; /* system */
tg_dat.system_type = SDT_386TRAPGT; /* trap gate */
tg_dat.dpl = dpl;
tg_dat.present = 1;
tg_dat.selector = KERNEL_CODE_SEL;
tg_dat.offset = (unsigned long)handler;
set_descr(&idt[index], &tg_dat);
}
/* Fonctions exportees */
void setup_idt()
{
struct __attribute__ ((packed)) {
unsigned short limit;
unsigned long base;
} idt_descr;
unsigned int i;
/* exceptions */
for (i = 0; i <= 31; i++)
set_interrupt_gate(i, 0, die);
/* interruptions externes */
for (i = 32; i <= 255; i++)
set_interrupt_gate(i, 0, ignore_it); /* Available for external interrupts via INTR pin */
idt_descr.limit = sizeof idt - 1;
idt_descr.base = (unsigned long)idt;
lidt(idt_descr);
}
void idt_set_trap_gate(unsigned int id, void *handler)
{
set_trap_gate(id, 0, handler);
}
void idt_set_interrupt_gate(unsigned int id, void *handler)
{
set_interrupt_gate(id, 0, handler);
}
void idt_set_system_gate(unsigned int id, void *handler)
{
set_trap_gate(id, 3, handler);
}