ISR/IRQ cleanup
This commit is contained in:
parent
0dbd5ab089
commit
a699c91ddd
@ -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
94
kernel/cpu/isr.c
Normal 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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user