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); }