ISR/IRQ cleanup

This commit is contained in:
Dale Weiler 2015-05-21 13:22:06 -04:00
parent 0dbd5ab089
commit a699c91ddd
6 changed files with 127 additions and 183 deletions

View File

@ -9,6 +9,8 @@
*/
#include <system.h>
#include <logging.h>
#include <module.h>
#include <printf.h>
/* Programmable interrupt controller */
#define PIC1 0x20
@ -78,31 +80,10 @@ void int_enable(void) {
}
/* Interrupt Requests */
extern void _irq0(void);
extern void _irq1(void);
extern void _irq2(void);
extern void _irq3(void);
extern void _irq4(void);
extern void _irq5(void);
extern void _irq6(void);
extern void _irq7(void);
extern void _irq8(void);
extern void _irq9(void);
extern void _irq10(void);
extern void _irq11(void);
extern void _irq12(void);
extern void _irq13(void);
extern void _irq14(void);
extern void _irq15(void);
static void (*irqs[])(void) = {
_irq0, _irq1, _irq2, _irq3, _irq4, _irq5, _irq6, _irq7,
_irq8, _irq9, _irq10, _irq11, _irq12, _irq13, _irq14, _irq15
};
#define IRQ_CHAIN_SIZE (sizeof(irqs)/sizeof(*irqs))
#define IRQ_CHAIN_DEPTH 4
#define IRQ_CHAIN_SIZE 16
#define IRQ_CHAIN_DEPTH 4
static void (*irqs[IRQ_CHAIN_SIZE])(void);
static irq_handler_chain_t irq_routines[IRQ_CHAIN_SIZE * IRQ_CHAIN_DEPTH] = { NULL };
void irq_install_handler(size_t irq, irq_handler_chain_t handler) {
@ -144,11 +125,17 @@ static void irq_remap(void) {
}
static void irq_setup_gates(void) {
for (size_t i = 0; i < IRQ_CHAIN_SIZE; i++)
for (size_t i = 0; i < IRQ_CHAIN_SIZE; i++) {
idt_set_gate(32 + i, irqs[i], 0x08, 0x8E);
}
}
void irq_install(void) {
char buffer[16];
for (int i = 0; i < IRQ_CHAIN_SIZE; i++) {
sprintf(buffer, "_irq%d", i);
irqs[i] = symbol_find(buffer);
}
irq_remap();
irq_setup_gates();
}

94
kernel/cpu/isr.c Normal file
View File

@ -0,0 +1,94 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
* This file is part of ToaruOS and is released under the terms
* of the NCSA / University of Illinois License - see LICENSE.md
* Copyright (C) 2011-2014 Kevin Lange
* Copyright (C) 2015 Dale Weiler
*
* Interrupt Service Requests
*/
#include <system.h>
#include <logging.h>
#include <module.h>
#include <printf.h>
/* The count is treated as is when setting up IDT gates. However there is an
* additional ISR for the system call vector which is handled explicitly since
* it's mapped at a different address.
*/
#define ISR_COUNT 32
static struct {
size_t index;
void (*stub)(void);
} isrs[32 + 1] __attribute__((used));
static irq_handler_t isr_routines[256] = { 0 };
void isrs_install_handler(size_t isrs, irq_handler_t handler) {
isr_routines[isrs] = handler;
}
void isrs_uninstall_handler(size_t isrs) {
isr_routines[isrs] = 0;
}
void isrs_install(void) {
char buffer[16];
for (int i = 0; i < ISR_COUNT; i++) {
sprintf(buffer, "_isr%d", i);
isrs[i].index = i;
isrs[i].stub = symbol_find(buffer);
}
isrs[ISR_COUNT].index = SYSCALL_VECTOR;
isrs[ISR_COUNT].stub = symbol_find("_isr127");
for (int i = 0; i < ISR_COUNT + 1; i++) {
idt_set_gate(isrs[i].index, isrs[i].stub, 0x08, 0x8E);
}
}
static const char *exception_messages[32] = {
"Division by zero",
"Debug",
"Non-maskable interrupt",
"Breakpoint",
"Detected overflow",
"Out-of-bounds",
"Invalid opcode",
"No coprocessor",
"Double fault",
"Coprocessor segment overrun",
"Bad TSS",
"Segment not present",
"Stack fault",
"General protection fault",
"Page fault",
"Unknown interrupt",
"Coprocessor fault",
"Alignment check",
"Machine check",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved"
};
void fault_handler(struct regs * r) {
irq_handler_t handler = isr_routines[r->int_no];
if (handler) {
handler(r);
} else {
debug_print(CRITICAL, "Unhandled exception: [%d] %s", r->int_no, exception_messages[r->int_no]);
HALT_AND_CATCH_FIRE("Process caused an unhandled exception", r);
STOP;
}
}

View File

@ -1,22 +0,0 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
* This file is part of ToaruOS and is released under the terms
* of the NCSA / University of Illinois License - see LICENSE.md
* Copyright (C) 2011-2014 Kevin Lange
*
* Interrupt Services Requests
*/
#include <system.h>
#include <logging.h>
extern irq_handler_t isrs_routines[256];
extern void fault_error(struct regs *r);
void fault_handler(struct regs *r) {
irq_handler_t handler;
handler = isrs_routines[r->int_no];
if (handler) {
handler(r);
} else {
fault_error(r);
}
}

View File

@ -1,134 +0,0 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
* This file is part of ToaruOS and is released under the terms
* of the NCSA / University of Illinois License - see LICENSE.md
* Copyright (C) 2013-2014 Kevin Lange
*/
#include <system.h>
#include <logging.h>
/*
* Exception Handlers
*/
extern void _isr0 (void);
extern void _isr1 (void);
extern void _isr2 (void);
extern void _isr3 (void);
extern void _isr4 (void);
extern void _isr5 (void);
extern void _isr6 (void);
extern void _isr7 (void);
extern void _isr8 (void);
extern void _isr9 (void);
extern void _isr10(void);
extern void _isr11(void);
extern void _isr12(void);
extern void _isr13(void);
extern void _isr14(void);
extern void _isr15(void);
extern void _isr16(void);
extern void _isr17(void);
extern void _isr18(void);
extern void _isr19(void);
extern void _isr20(void);
extern void _isr21(void);
extern void _isr22(void);
extern void _isr23(void);
extern void _isr24(void);
extern void _isr25(void);
extern void _isr26(void);
extern void _isr27(void);
extern void _isr28(void);
extern void _isr29(void);
extern void _isr30(void);
extern void _isr31(void);
extern void _isr127(void);
irq_handler_t isrs_routines[256] = { NULL };
void isrs_install_handler(size_t isrs, irq_handler_t handler) {
isrs_routines[isrs] = handler;
}
void isrs_uninstall_handler(size_t isrs) {
isrs_routines[isrs] = 0;
}
void isrs_install(void) {
/* Exception Handlers */
memset(isrs_routines, 0x00, sizeof(isrs_routines));
idt_set_gate(0, _isr0, 0x08, 0x8E);
idt_set_gate(1, _isr1, 0x08, 0x8E);
idt_set_gate(2, _isr2, 0x08, 0x8E);
idt_set_gate(3, _isr3, 0x08, 0x8E);
idt_set_gate(4, _isr4, 0x08, 0x8E);
idt_set_gate(5, _isr5, 0x08, 0x8E);
idt_set_gate(6, _isr6, 0x08, 0x8E);
idt_set_gate(7, _isr7, 0x08, 0x8E);
idt_set_gate(8, _isr8, 0x08, 0x8E);
idt_set_gate(9, _isr9, 0x08, 0x8E);
idt_set_gate(10, _isr10, 0x08, 0x8E);
idt_set_gate(11, _isr11, 0x08, 0x8E);
idt_set_gate(12, _isr12, 0x08, 0x8E);
idt_set_gate(13, _isr13, 0x08, 0x8E);
idt_set_gate(14, _isr14, 0x08, 0x8E);
idt_set_gate(15, _isr15, 0x08, 0x8E);
idt_set_gate(16, _isr16, 0x08, 0x8E);
idt_set_gate(17, _isr17, 0x08, 0x8E);
idt_set_gate(18, _isr18, 0x08, 0x8E);
idt_set_gate(19, _isr19, 0x08, 0x8E);
idt_set_gate(20, _isr20, 0x08, 0x8E);
idt_set_gate(21, _isr21, 0x08, 0x8E);
idt_set_gate(22, _isr22, 0x08, 0x8E);
idt_set_gate(23, _isr23, 0x08, 0x8E);
idt_set_gate(24, _isr24, 0x08, 0x8E);
idt_set_gate(25, _isr25, 0x08, 0x8E);
idt_set_gate(26, _isr26, 0x08, 0x8E);
idt_set_gate(27, _isr27, 0x08, 0x8E);
idt_set_gate(28, _isr28, 0x08, 0x8E);
idt_set_gate(29, _isr29, 0x08, 0x8E);
idt_set_gate(30, _isr30, 0x08, 0x8E);
idt_set_gate(31, _isr31, 0x08, 0x8E);
idt_set_gate(SYSCALL_VECTOR, _isr127, 0x08, 0x8E);
}
static const char *exception_messages[32] = {
"Division by zero", /* 0 */
"Debug",
"Non-maskable interrupt",
"Breakpoint",
"Detected overflow",
"Out-of-bounds", /* 5 */
"Invalid opcode",
"No coprocessor",
"Double fault",
"Coprocessor segment overrun",
"Bad TSS", /* 10 */
"Segment not present",
"Stack fault",
"General protection fault",
"Page fault",
"Unknown interrupt", /* 15 */
"Coprocessor fault",
"Alignment check",
"Machine check",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved"
};
void fault_error(struct regs *r) {
debug_print(CRITICAL, "Unhandled exception: [%d] %s", r->int_no, exception_messages[r->int_no]);
HALT_AND_CATCH_FIRE("Process caused an unhandled exception", r);
STOP;
}

View File

@ -19,6 +19,8 @@ typedef struct {
char * deps;
} module_data_t;
void (* symbol_find(const char * name))(void);
extern int module_quickcheck(void * blob);
extern void * module_load_direct(void * blob, size_t size);
extern void * module_load(char * filename);

View File

@ -16,13 +16,30 @@
static hashmap_t * symboltable = NULL;
static hashmap_t * modules = NULL;
extern char kernel_symbols_start[];
extern char kernel_symbols_end[];
typedef struct {
uintptr_t addr;
char name[];
} kernel_symbol_t;
extern char kernel_symbols_start[];
extern char kernel_symbols_end[];
/* Cannot use symboltable here because symbol_find is used during initialization
* of IRQs and ISRs.
*/
void (* symbol_find(const char * name))(void) {
kernel_symbol_t * k = (kernel_symbol_t *)&kernel_symbols_start;
while ((uintptr_t)k < (uintptr_t)&kernel_symbols_end) {
if (strcmp(k->name, name)) {
k = (kernel_symbol_t *)((uintptr_t)k + sizeof *k + strlen(k->name) + 1);
continue;
}
return (void (*)(void))k->addr;
}
return NULL;
}
int module_quickcheck(void * blob) {