BarryServer : Git

All the code for all my projects
// BarryServer : Git / Orion / blob / 1628fcfdfdf2978ed9ccac96ee7d13bb3dc43a01 / proc / irqs.c

// Related

Orion

Barry Importing existing Orion kernel d41a53c (2 years, 4 months 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;
}