183 lines
5.7 KiB
C
Executable file
183 lines
5.7 KiB
C
Executable file
/*
|
|
File: exceptions.C
|
|
|
|
Author: R. Bettati
|
|
Department of Computer Science
|
|
Texas A&M University
|
|
Date : 12/09/05
|
|
|
|
*/
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* DEFINES */
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
/* -- (none) -- */
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* INCLUDES */
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
#include "assert.H"
|
|
#include "utils.H"
|
|
#include "console.H"
|
|
#include "idt.H"
|
|
#include "exceptions.H"
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* EXTERNS */
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
/* The low-level functions (defined in file 'IDT::low.s') that handle the
|
|
32 Intel-defined CPU exceptions.
|
|
These functions are actually merely stubs that put the error code and
|
|
the exception code on the stack and then call a low-level function, which
|
|
in turn calls the exception dispatcher (defined in 'exceptions.H').
|
|
Yes, there are more efficient ways to handle exceptions, but they require more
|
|
code replication.
|
|
*/
|
|
extern "C" void isr0();
|
|
extern "C" void isr1();
|
|
extern "C" void isr2();
|
|
extern "C" void isr3();
|
|
extern "C" void isr4();
|
|
extern "C" void isr5();
|
|
extern "C" void isr6();
|
|
extern "C" void isr7();
|
|
extern "C" void isr8();
|
|
extern "C" void isr9();
|
|
extern "C" void isr10();
|
|
extern "C" void isr11();
|
|
extern "C" void isr12();
|
|
extern "C" void isr13();
|
|
extern "C" void isr14();
|
|
extern "C" void isr15();
|
|
extern "C" void isr16();
|
|
extern "C" void isr17();
|
|
extern "C" void isr18();
|
|
extern "C" void isr19();
|
|
extern "C" void isr20();
|
|
extern "C" void isr21();
|
|
extern "C" void isr22();
|
|
extern "C" void isr23();
|
|
extern "C" void isr24();
|
|
extern "C" void isr25();
|
|
extern "C" void isr26();
|
|
extern "C" void isr27();
|
|
extern "C" void isr28();
|
|
extern "C" void isr29();
|
|
extern "C" void isr30();
|
|
extern "C" void isr31();
|
|
|
|
extern "C" void lowlevel_dispatch_exception(REGS * _r) {
|
|
ExceptionHandler::dispatch_exception(_r);
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* STATIC VARIABLES */
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
ExceptionHandler * ExceptionHandler::handler_table[ExceptionHandler::EXCEPTION_TABLE_SIZE];
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* EXPORTED EXCEPTION DISPATCHER FUNCTIONS */
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
void ExceptionHandler::init_dispatcher() {
|
|
|
|
/* -- INITIALIZE LOW-LEVEL EXCEPTION HANDLERS */
|
|
/* Add any new ISRs to the IDT here using IDT::set_gate */
|
|
IDT::set_gate( 0, (unsigned) isr0, 0x08, 0x8E);
|
|
IDT::set_gate( 1, (unsigned) isr1, 0x08, 0x8E);
|
|
IDT::set_gate( 2, (unsigned) isr2, 0x08, 0x8E);
|
|
IDT::set_gate( 3, (unsigned) isr3, 0x08, 0x8E);
|
|
IDT::set_gate( 4, (unsigned) isr4, 0x08, 0x8E);
|
|
IDT::set_gate( 5, (unsigned) isr5, 0x08, 0x8E);
|
|
IDT::set_gate( 6, (unsigned) isr6, 0x08, 0x8E);
|
|
IDT::set_gate( 7, (unsigned) isr7, 0x08, 0x8E);
|
|
|
|
IDT::set_gate( 8, (unsigned) isr8, 0x08, 0x8E);
|
|
IDT::set_gate( 9, (unsigned) isr9, 0x08, 0x8E);
|
|
IDT::set_gate(10, (unsigned)isr10, 0x08, 0x8E);
|
|
IDT::set_gate(11, (unsigned)isr11, 0x08, 0x8E);
|
|
IDT::set_gate(12, (unsigned)isr12, 0x08, 0x8E);
|
|
IDT::set_gate(13, (unsigned)isr13, 0x08, 0x8E);
|
|
IDT::set_gate(14, (unsigned)isr14, 0x08, 0x8E);
|
|
IDT::set_gate(15, (unsigned)isr15, 0x08, 0x8E);
|
|
|
|
IDT::set_gate(16, (unsigned)isr16, 0x08, 0x8E);
|
|
IDT::set_gate(17, (unsigned)isr17, 0x08, 0x8E);
|
|
IDT::set_gate(18, (unsigned)isr18, 0x08, 0x8E);
|
|
IDT::set_gate(19, (unsigned)isr19, 0x08, 0x8E);
|
|
IDT::set_gate(20, (unsigned)isr20, 0x08, 0x8E);
|
|
IDT::set_gate(21, (unsigned)isr21, 0x08, 0x8E);
|
|
IDT::set_gate(22, (unsigned)isr22, 0x08, 0x8E);
|
|
IDT::set_gate(23, (unsigned)isr23, 0x08, 0x8E);
|
|
|
|
IDT::set_gate(24, (unsigned)isr24, 0x08, 0x8E);
|
|
IDT::set_gate(25, (unsigned)isr25, 0x08, 0x8E);
|
|
IDT::set_gate(26, (unsigned)isr26, 0x08, 0x8E);
|
|
IDT::set_gate(27, (unsigned)isr27, 0x08, 0x8E);
|
|
IDT::set_gate(28, (unsigned)isr28, 0x08, 0x8E);
|
|
IDT::set_gate(29, (unsigned)isr29, 0x08, 0x8E);
|
|
IDT::set_gate(30, (unsigned)isr30, 0x08, 0x8E);
|
|
IDT::set_gate(31, (unsigned)isr31, 0x08, 0x8E);
|
|
|
|
/* -- INITIALIZE THE HIGH-LEVEL EXCEPTION HANDLER */
|
|
int i;
|
|
for(i = 0; i < EXCEPTION_TABLE_SIZE; i++) {
|
|
handler_table[i] = NULL;
|
|
}
|
|
}
|
|
|
|
void ExceptionHandler::dispatch_exception(REGS * _r) {
|
|
|
|
/* -- EXCEPTION NUMBER */
|
|
unsigned int exc_no = _r->int_no;
|
|
|
|
Console::puts("EXCEPTION DISPATCHER: exc_no = ");
|
|
Console::putui(exc_no);
|
|
Console::puts("\n");
|
|
|
|
assert((exc_no >= 0) && (exc_no < EXCEPTION_TABLE_SIZE));
|
|
|
|
/* -- HAS A HANDLER BEEN REGISTERED FOR THIS EXCEPTION NO? */
|
|
ExceptionHandler * handler = handler_table[exc_no];
|
|
|
|
if (!handler) {
|
|
/* --- NO HANDLER HAS BEEN REGISTERED. SIMPLY RETURN AN ERROR. */
|
|
Console::puts("NO DEFAULT EXCEPTION HANDLER REGISTERED\n");
|
|
abort();
|
|
}
|
|
else {
|
|
/* -- HANDLE THE EXCEPTION OR INTERRUPT */
|
|
handler->handle_exception(_r);
|
|
}
|
|
|
|
}
|
|
|
|
void ExceptionHandler::register_handler(unsigned int _isr_code,
|
|
ExceptionHandler * _handler) {
|
|
|
|
assert(_isr_code >= 0 && _isr_code < EXCEPTION_TABLE_SIZE);
|
|
|
|
handler_table[_isr_code] = _handler;
|
|
|
|
Console::puts("Installed exception handler at ISR ");
|
|
Console::putui(_isr_code);
|
|
Console::puts("\n");
|
|
|
|
}
|
|
|
|
void ExceptionHandler::deregister_handler(unsigned int _isr_code) {
|
|
assert(_isr_code >= 0 && _isr_code < EXCEPTION_TABLE_SIZE);
|
|
|
|
handler_table[_isr_code] = NULL;
|
|
|
|
Console::puts("UNINSTALLED exception handler at ISR ");
|
|
Console::putui(_isr_code);
|
|
Console::puts("\n");
|
|
|
|
}
|
|
|
|
|