Orion
Barry Importing existing Orion kernel d41a53c (3 years, 1 month ago)
/*
* This file contains the abstraction for exceptions and interrupts. It
* presents a system of registrable exception/interrupt handlers. It also
* contains the generic handlers, which pass control to the appropriate
* registered handler. This file does not deal with dispatching
* messages/signals to processes on an interrupt.
*/
#include <stdint.h>
#include "proc.h"
#include "../proc/proc.h"
#include "../task/task.h"
#include "../io.h"
#include "../screen.h"
void (**exceptions)(InterruptFrame *);
void (**interrupts)(InterruptFrame *);
/* Register an exception handler */
void
register_exception(int num, void (*addr)(InterruptFrame *))
{
if (num >= 0 && num < 32)
exceptions[num] = addr;
}
/* Register an interrupt handler */
void
register_interrupt(int num, void (*addr)(InterruptFrame *))
{
if (num >= 0 && num < 224)
interrupts[num] = addr;
}
/* Call the appropriate exception handler */
uintptr_t
exc_handler(InterruptFrame frame)
{
uint8_t num = frame.intNo & 0xFF;
/* System Call */
if (num == 0x80)
syscall_handler(&frame);
/* Other exception */
else if (exceptions[num])
exceptions[num](&frame);
else
panic("Unhandled exception %d (%#x) @ %#.8x [CPU#%d]\n"
"EFLAGS: %#.8x",
num, frame.errCode, frame.eip, CPUID, frame.eflags);
/* Send EOI */
LAPIC(0xB0) = 0;
if (current)
if (current->tls)
return current->tls->start + 4;
return 0;
}
/* Call the appropriate interrupt handler */
uintptr_t
irq_handler(InterruptFrame frame)
{
uint8_t num = (frame.intNo & 0xFF) - 32;
if (interrupts[num])
interrupts[num](&frame);
/* Send EOI */
outb(0x20, 0x20);
if (num >= 8)
outb(0xA0, 0x20);
LAPIC(0xB0) = 0;
if (current)
if (current->tls)
return current->tls->start + 4;
return 0;
}