diff options
Diffstat (limited to 'kernel/l0/idt.c')
-rw-r--r-- | kernel/l0/idt.c | 253 |
1 files changed, 0 insertions, 253 deletions
diff --git a/kernel/l0/idt.c b/kernel/l0/idt.c deleted file mode 100644 index 2f244e3..0000000 --- a/kernel/l0/idt.c +++ /dev/null @@ -1,253 +0,0 @@ -#include <idt.h> -#include <gdt.h> -#include <sys.h> -#include <string.h> -#include <dbglog.h> - -struct idt_entry { - uint16_t base_lo; //Low part of address to jump to - uint16_t sel; //Kernel segment selector - uint8_t always0; - uint8_t type_attr; //Type - uint16_t base_hi; //High part of address to jump to -} __attribute__((packed)); -typedef struct idt_entry idt_entry_t; - -struct idt_ptr { - uint16_t limit; - uint32_t base; -} __attribute__((packed)); -typedef struct idt_ptr idt_ptr_t; - -#define GATE_TYPE_INTERRUPT 14 // IF is cleared on interrupt -#define GATE_TYPE_TRAP 15 // IF stays as is - -#define GATE_PRESENT (1<<7) -#define GATE_DPL_SHIFT 5 - - -void isr0(); -void isr1(); -void isr2(); -void isr3(); -void isr4(); -void isr5(); -void isr6(); -void isr7(); -void isr8(); -void isr9(); -void isr10(); -void isr11(); -void isr12(); -void isr13(); -void isr14(); -void isr15(); -void isr16(); -void isr17(); -void isr18(); -void isr19(); -void isr20(); -void isr21(); -void isr22(); -void isr23(); -void isr24(); -void isr25(); -void isr26(); -void isr27(); -void isr28(); -void isr29(); -void isr30(); -void isr31(); - -void irq0(); -void irq1(); -void irq2(); -void irq3(); -void irq4(); -void irq5(); -void irq6(); -void irq7(); -void irq8(); -void irq9(); -void irq10(); -void irq11(); -void irq12(); -void irq13(); -void irq14(); -void irq15(); - -void syscall64(); - -// ************************************************************ -// Handler code - -static idt_entry_t idt_entries[256]; -static idt_ptr_t idt_ptr; - -static isr_handler_t irq_handlers[16] = {0}; -static isr_handler_t ex_handlers[32] = {0}; - -/* Called in interrupt.s when an exception fires (interrupt 0 to 31) */ -void idt_exHandler(registers_t *regs) { - if (ex_handlers[regs->int_no] != 0) { - ex_handlers[regs->int_no](regs); - } else { - //TODO: make sure all exceptions happenning in userspace do not cause kernel panic... - dbg_printf("Unhandled exception: %i\n", regs->int_no); - dbg_dump_registers(regs); - PANIC("Unhandled exception"); - } -} - -/* Called in interrupt.s when an IRQ fires (interrupt 32 to 47) */ -void idt_irqHandler(registers_t *regs) { - if (regs->err_code > 7) { - outb(0xA0, 0x20); - } - outb(0x20, 0x20); - - dbg_printf("IRQ %i\n", regs->err_code); - if (irq_handlers[regs->err_code] != 0) { - irq_handlers[regs->err_code](regs); - } -} - -/* Caled in interrupt.s when a syscall is called */ -void idt_syscallHandler(registers_t *regs) { - dbg_printf("Syscall %i\n", regs->int_no); - // do nothing, yet. -} - -/* For internal use only. Sets up an entry of the IDT with given parameters. */ -static void idt_set_gate(uint8_t num, void (*fun)(), uint8_t type) { - uint32_t base = (uint32_t)fun; - - idt_entries[num].base_lo = base & 0xFFFF; - idt_entries[num].base_hi = (base >> 16) & 0xFFFF; - - idt_entries[num].sel = K_CODE_SEGMENT; - idt_entries[num].always0 = 0; - idt_entries[num].type_attr = GATE_PRESENT - | (3 << GATE_DPL_SHIFT) // accessible from user mode - | type; -} - -static const struct { - uint8_t num; - void (*fun)(); - uint8_t type; -} gates[] = { - // Most processor exceptions are traps and handling them - // should be preemptible - { 0, isr0, GATE_TYPE_TRAP }, - { 1, isr1, GATE_TYPE_TRAP }, - { 2, isr2, GATE_TYPE_TRAP }, - { 3, isr3, GATE_TYPE_TRAP }, - { 4, isr4, GATE_TYPE_TRAP }, - { 5, isr5, GATE_TYPE_TRAP }, - { 6, isr6, GATE_TYPE_TRAP }, - { 7, isr7, GATE_TYPE_TRAP }, - { 8, isr8, GATE_TYPE_TRAP }, - { 9, isr9, GATE_TYPE_TRAP }, - { 10, isr10, GATE_TYPE_TRAP }, - { 11, isr11, GATE_TYPE_TRAP }, - { 12, isr12, GATE_TYPE_TRAP }, - { 13, isr13, GATE_TYPE_TRAP }, - { 14, isr14, GATE_TYPE_INTERRUPT }, // reenables interrupts later on - { 15, isr15, GATE_TYPE_TRAP }, - { 16, isr16, GATE_TYPE_TRAP }, - { 17, isr17, GATE_TYPE_TRAP }, - { 18, isr18, GATE_TYPE_TRAP }, - { 19, isr19, GATE_TYPE_TRAP }, - { 20, isr20, GATE_TYPE_TRAP }, - { 21, isr21, GATE_TYPE_TRAP }, - { 22, isr22, GATE_TYPE_TRAP }, - { 23, isr23, GATE_TYPE_TRAP }, - { 24, isr24, GATE_TYPE_TRAP }, - { 25, isr25, GATE_TYPE_TRAP }, - { 26, isr26, GATE_TYPE_TRAP }, - { 27, isr27, GATE_TYPE_TRAP }, - { 28, isr28, GATE_TYPE_TRAP }, - { 29, isr29, GATE_TYPE_TRAP }, - { 30, isr30, GATE_TYPE_TRAP }, - { 31, isr31, GATE_TYPE_TRAP }, - - // IRQs are not preemptible ; an IRQ handler should do the bare minimum - // (communication with the hardware), and then pass a message to a worker - // process in order to do further processing - { 32, irq0, GATE_TYPE_INTERRUPT }, - { 33, irq1, GATE_TYPE_INTERRUPT }, - { 34, irq2, GATE_TYPE_INTERRUPT }, - { 35, irq3, GATE_TYPE_INTERRUPT }, - { 36, irq4, GATE_TYPE_INTERRUPT }, - { 37, irq5, GATE_TYPE_INTERRUPT }, - { 38, irq6, GATE_TYPE_INTERRUPT }, - { 39, irq7, GATE_TYPE_INTERRUPT }, - { 40, irq8, GATE_TYPE_INTERRUPT }, - { 41, irq9, GATE_TYPE_INTERRUPT }, - { 42, irq10, GATE_TYPE_INTERRUPT }, - { 43, irq11, GATE_TYPE_INTERRUPT }, - { 44, irq12, GATE_TYPE_INTERRUPT }, - { 45, irq13, GATE_TYPE_INTERRUPT }, - { 46, irq14, GATE_TYPE_INTERRUPT }, - { 47, irq15, GATE_TYPE_INTERRUPT }, - - // Of course, syscalls are preemptible - { 64, syscall64, GATE_TYPE_TRAP }, - - { 0, 0, 0 } -}; - -/* Remaps the IRQs. Sets up the IDT. */ -void idt_init() { - memset((uint8_t*)&idt_entries, 0, sizeof(idt_entry_t) * 256); - - //Remap the IRQ table - outb(0x20, 0x11); - outb(0xA0, 0x11); - outb(0x21, 0x20); - outb(0xA1, 0x28); - outb(0x21, 0x04); - outb(0xA1, 0x02); - outb(0x21, 0x01); - outb(0xA1, 0x01); - outb(0x21, 0x0); - outb(0xA1, 0x0); - - for (int i = 0; gates[i].type != 0; i++) { - idt_set_gate(gates[i].num, gates[i].fun, gates[i].type); - } - - idt_ptr.limit = (sizeof(idt_entry_t) * 256) - 1; - idt_ptr.base = (uint32_t)&idt_entries; - - asm volatile ("lidt %0"::"m"(idt_ptr):"memory"); - - // Some setup calls that come later on are not preemptible, - // so we wait until then to enable interrupts. -} - -/* Sets up an IRQ handler for given IRQ. */ -void idt_set_irq_handler(int number, isr_handler_t func) { - if (number < 16 && number >= 0) { - irq_handlers[number] = func; - } -} - -/* Sets up a handler for a processor exception */ -void idt_set_ex_handler(int number, isr_handler_t func) { - if (number >= 0 && number < 32) { - ex_handlers[number] = func; - } -} - -void dbg_dump_registers(registers_t *regs) { - dbg_printf("/ Exception %i\n", regs->int_no); - dbg_printf("| EAX: 0x%p EBX: 0x%p ECX: 0x%p EDX: 0x%p\n", regs->eax, regs->ebx, regs->ecx, regs->edx); - dbg_printf("| EDI: 0x%p ESI: 0x%p ESP: 0x%p EBP: 0x%p\n", regs->edi, regs->esi, regs->esp, regs->ebp); - dbg_printf("| EIP: 0x%p CS : 0x%p DS : 0x%p SS : 0x%p\n", regs->eip, regs->cs, regs->ds, regs->ss); - dbg_printf("\\ EFl: 0x%p I# : 0x%p Err: 0x%p\n", regs->eflags, regs->int_no, regs->err_code); -} - -/* vim: set ts=4 sw=4 tw=0 noet :*/ - |