[INTERRUPTS] Exception handling

This commit is contained in:
2016-11-20 11:26:32 +01:00
parent 0120df249e
commit 5dd42d26ae
11 changed files with 309 additions and 3 deletions

View File

@@ -0,0 +1,67 @@
#include <int.h>
#include <debug.h>
#include <registers.h>
#include <string.h>
#include <stdint.h>
struct int_gate_descriptor idt[NUM_INTERRUPTS];
struct idtr idtr;
int_handler_t int_handlers[NUM_INTERRUPTS];
void idt_set(uint32_t num, void *vector, uint16_t cs, uint8_t ist, uint8_t flags)
{
uintptr_t v = (uintptr_t)vector;
idt[num].base_l = v & 0xFFFF;
idt[num].base_m = (v >> 16) & 0xFFFF;
idt[num].base_h = (v >> 32) & 0xFFFFFFFF;
idt[num].cs = cs;
idt[num].ist = ist;
idt[num].flags = flags;
}
void interrupt_init()
{
// Clear IDT and interrupt handler list
memset(idt, 0, sizeof(idt));
memset(int_handlers, 0, sizeof(int_handlers));
// Register all vectors in the IDT
extern void *isr_table[];
for(int i=0; i < NUM_INTERRUPTS; i++)
{
idt_set(i, isr_table[i], 0x8, 0,
(IDT_PRESENT | IDT_DPL0 | IDT_INTERRUPT));
}
// Setup pointer and load IDT
idtr.addr = (uint64_t)idt;
idtr.len = sizeof(idt)-1;
load_idt(&idtr);
}
int_handler_t register_int_handler(uint32_t num, int_handler_t h)
{
// Replace the handler for an interrupt
// Return the old handler
int_handler_t old = int_handlers[num];
int_handlers[num] = h;
return old;
}
registers_t *int_handler(registers_t *r)
{
// If a handler is registered, pass everything onto it
if(int_handlers[r->int_no])
return int_handlers[r->int_no](r);
debug("\n===============================================================================\n");
debug_error("Unhandled interrupt!\n");
print_registers(r);
#ifndef NDEBUG
asm("int_handler_breakpoint:");
#endif
for(;;);
}

View File

@@ -0,0 +1,28 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
print('''
.intel_syntax noprefix
.extern isr_common
''')
print('// Interrupt Service Routines')
for i in range(255):
print('''isr{0}:
cli
{1}
push {0}
jmp isr_common
'''.format(i,
'push 0' if i not in [8, 10, 11, 12, 13, 14, 17] else 'nop'))
print('''
// Vector table
.section .data
.global isr_table
isr_table:
''')
for i in range(255):
print(' .quad isr{}'.format(i))

View File

@@ -0,0 +1,49 @@
.intel_syntax noprefix
.extern int_handler
.global isr_common
.global isr_return
isr_common:
// Push all registers
push r15
push r14
push r13
push r12
push r11
push r10
push r9
push r8
push rbp
push rdi
push rsi
push rdx
push rcx
push rbx
push rax
mov rdi, rsp
call int_handler
mov rdi, rax
isr_return:
// Return and restore stack
mov rsp, rdi
pop rax
pop rbx
pop rcx
pop rdx
pop rsi
pop rdi
pop rbp
pop r8
pop r9
pop r10
pop r11
pop r12
pop r13
pop r14
pop r15
// Pop error code and fault number
add rsp, 16
iretq