BarryServer : Git

All the code for all my projects
// BarryServer : Git / Orion / blob / 7ae31b03c38925f5d527e6303765925586731209 / proc / idt.c

// Related

Orion

Barry Importing existing Orion kernel d41a53c (2 years, 4 months ago)
/*
 * This file deals with the Interrupt Descriptor Table.  It creates a simple
 * IDT, with hard-coded handler functions.  It is these handler functions that
 * can run custom handlers, registered at runtime.  This file does not deal with
 * dispatching messages/signals to processes on an interrupt.
 */

#include <stdint.h>
#include <string.h>
#include "proc.h"
#include "../mem/heap.h"
#include "../mem/frame.h"
#include "../screen.h"

/* Structure for IDT entry */
static struct IDTEntry {
	uint16_t offsetLower, selector;
	uint8_t zero, typeAttr;
	uint16_t offsetHigher;
} __attribute__((packed)) *IDT;

void load_idt(uint32_t ptr[2]);
/* Exceptions */
void exc0(void);
void exc1(void);
void exc2(void);
void exc3(void);
void exc4(void);
void exc5(void);
void exc6(void);
void exc7(void);
void exc8(void);
void exc9(void);
void exc10(void);
void exc11(void);
void exc12(void);
void exc13(void);
void exc14(void);
void exc15(void);
void exc16(void);
void exc17(void);
void exc18(void);
void exc19(void);
void exc20(void);
void exc30(void);
void exc128(void); /* syscall */
/* Interrutps */
void irq0(void);
void irq1(void);
void irq2(void);
void irq3(void);
void irq4(void);
void irq5(void);
void irq6(void);
void irq7(void);
void irq8(void);
void irq9(void);
void irq10(void);
void irq11(void);
void irq12(void);
void irq13(void);
void irq14(void);
void irq15(void);

extern void (**exceptions)(InterruptFrame *);
extern void (**interrupts)(InterruptFrame *);

/* Install an IDT entry */
static void
install_idt_entry(uint8_t num, uint32_t addr)
{
	IDT[num].offsetLower = addr & 0xFFFF;
	IDT[num].selector = 0x08;
	IDT[num].zero = 0;
	IDT[num].typeAttr = 0x8E | 0x60; /* Allowed from ring 3 */
	IDT[num].offsetHigher = addr >> 16;
}

/* Initialise the IDT */
void
init_idt(void)
{
	IDT = (void *) alloc_frames(1);

	/* Install exceptions */
	install_idt_entry(0, (uint32_t) exc0);
	install_idt_entry(1, (uint32_t) exc1);
	install_idt_entry(2, (uint32_t) exc2);
	install_idt_entry(3, (uint32_t) exc3);
	install_idt_entry(4, (uint32_t) exc4);
	install_idt_entry(5, (uint32_t) exc5);
	install_idt_entry(6, (uint32_t) exc6);
	install_idt_entry(7, (uint32_t) exc7);
	install_idt_entry(8, (uint32_t) exc8);
	install_idt_entry(9, (uint32_t) exc9);
	install_idt_entry(10, (uint32_t) exc10);
	install_idt_entry(11, (uint32_t) exc11);
	install_idt_entry(12, (uint32_t) exc12);
	install_idt_entry(13, (uint32_t) exc13);
	install_idt_entry(14, (uint32_t) exc14);
	install_idt_entry(15, (uint32_t) exc15);
	install_idt_entry(16, (uint32_t) exc16);
	install_idt_entry(17, (uint32_t) exc17);
	install_idt_entry(18, (uint32_t) exc18);
	install_idt_entry(19, (uint32_t) exc19);
	install_idt_entry(20, (uint32_t) exc20);
	install_idt_entry(30, (uint32_t) exc30);

	/* Install interrutps */
	install_idt_entry(32, (uint32_t) irq0);
	install_idt_entry(33, (uint32_t) irq1);
	install_idt_entry(34, (uint32_t) irq2);
	install_idt_entry(35, (uint32_t) irq3);
	install_idt_entry(36, (uint32_t) irq4);
	install_idt_entry(37, (uint32_t) irq5);
	install_idt_entry(38, (uint32_t) irq6);
	install_idt_entry(39, (uint32_t) irq7);
	install_idt_entry(40, (uint32_t) irq8);
	install_idt_entry(41, (uint32_t) irq9);
	install_idt_entry(42, (uint32_t) irq10);
	install_idt_entry(43, (uint32_t) irq11);
	install_idt_entry(44, (uint32_t) irq12);
	install_idt_entry(45, (uint32_t) irq13);
	install_idt_entry(46, (uint32_t) irq14);
	install_idt_entry(47, (uint32_t) irq15);

	/* Install syscall handler */
	install_idt_entry(128, (uint32_t) exc128);

	exceptions = (void (**)(InterruptFrame *)) (IDT + 256);
	interrupts = (void (**)(InterruptFrame *)) (exceptions + 32);
	memset(exceptions, 0, 1024);

	kprintf("Loaded IDT @ %#.8x, Exceptions @ %#.8x, Interrupts @ %#.8x",
	        IDT, exceptions, interrupts);
}

/* Load the IDT */
void
cpu_load_idt(void)
{
	uint32_t idtAddr, idtPtr[2];
	idtAddr = (uint32_t) IDT;
	idtPtr[0] = sizeof(struct IDTEntry) * 256;
	idtPtr[0] += (idtAddr & 0xFFFF) << 16;
	idtPtr[1] = idtAddr >> 16;
	load_idt(idtPtr);
}