diff options
author | Anton Kling <anton@kling.gg> | 2024-02-09 14:08:28 +0100 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2024-02-09 14:08:28 +0100 |
commit | a8ffc46136eb16adc87fb520c724467d1295a854 (patch) | |
tree | 2d1758a4e3c5b6ef8430c5a6b1aca7249ef7a56d /kernel/cpu | |
parent | 581ac7e072633f68deed5c5d343603c053895907 (diff) |
Kernel/Interrupts: Restructure how interrupts are handeled in the kernel
Now all interrupts go through a common stub which will make certain
signal handlers easier to implement
Diffstat (limited to 'kernel/cpu')
-rw-r--r-- | kernel/cpu/idt.c | 60 | ||||
-rw-r--r-- | kernel/cpu/idt.h | 269 | ||||
-rw-r--r-- | kernel/cpu/int_syscall.s | 21 | ||||
-rw-r--r-- | kernel/cpu/syscall.c | 13 |
4 files changed, 324 insertions, 39 deletions
diff --git a/kernel/cpu/idt.c b/kernel/cpu/idt.c index d381990..823cc2a 100644 --- a/kernel/cpu/idt.c +++ b/kernel/cpu/idt.c @@ -39,11 +39,6 @@ void format_descriptor(u32 offset, u16 code_segment, u8 type_attribute, descriptor->zero = 0; } -void install_handler(void (*handler_function)(), u16 type_attribute, u8 entry) { - format_descriptor((u32)handler_function, KERNEL_CODE_SEGMENT_OFFSET, - type_attribute, &IDT_Entry[entry]); -} - __attribute__((no_caller_saved_registers)) void EOI(u8 irq) { if (irq > 7) outb(SLAVE_PIC_COMMAND_PORT, 0x20); @@ -51,7 +46,7 @@ __attribute__((no_caller_saved_registers)) void EOI(u8 irq) { outb(MASTER_PIC_COMMAND_PORT, 0x20); } -__attribute__((interrupt)) void general_protection_fault(registers_t *regs) { +void general_protection_fault(reg_t *regs) { klog("General Protetion Fault", 0x1); kprintf(" Error Code: %x\n", regs->error_code); kprintf("Instruction Pointer: %x\n", regs->eip); @@ -62,7 +57,7 @@ __attribute__((interrupt)) void general_protection_fault(registers_t *regs) { EOI(0xD - 8); } -__attribute__((interrupt)) void double_fault(registers_t *regs) { +void double_fault(registers_t *regs) { (void)regs; klog("DOUBLE FAULT", LOG_ERROR); asm("hlt"); @@ -77,7 +72,7 @@ void jump_process(const process_t *p) { void none_save_switch(void); extern PageDirectory *active_directory; -__attribute__((interrupt)) void page_fault(registers_t *regs) { +void page_fault(reg_t *regs) { volatile uint32_t cr2; asm volatile("mov %%cr2, %0" : "=r"(cr2)); kprintf("CR2: %x\n", cr2); @@ -190,7 +185,56 @@ void IRQ_clear_mask(unsigned char IRQline) { outb(port, value); } +// TODO: Maybe lay these out using assembly, macro or via a linker +// script? +void *isr_list[] = { + isr0, isr1, isr2, isr3, isr4, isr5, isr6, isr7, isr8, + isr9, isr10, isr11, isr12, isr13, isr14, isr15, isr16, isr17, + isr18, isr19, isr20, isr21, isr22, isr23, isr24, isr25, isr26, + isr27, isr28, isr29, isr30, isr31, isr32, isr33, isr34, isr35, + isr36, isr37, isr38, isr39, isr40, isr41, isr42, isr43, isr44, + isr45, isr46, isr47, isr48, isr49, isr50, isr51, isr52, isr53, + isr54, isr55, isr56, isr57, isr58, isr59, isr60, isr61, isr62, + isr63, isr64, isr65, isr66, isr67, isr68, isr69, isr70, isr71, + isr72, isr73, isr74, isr75, isr76, isr77, isr78, isr79, isr80, + isr81, isr82, isr83, isr84, isr85, isr86, isr87, isr88, isr89, + isr90, isr91, isr92, isr93, isr94, isr95, isr96, isr97, isr98, + isr99, isr100, isr101, isr102, isr103, isr104, isr105, isr106, isr107, + isr108, isr109, isr110, isr111, isr112, isr113, isr114, isr115, isr116, + isr117, isr118, isr119, isr120, isr121, isr122, isr123, isr124, isr125, + isr126, isr127, isr128, isr129, isr130, isr131, isr132, isr133, isr134, + isr135, isr136, isr137, isr138, isr139, isr140, isr141, isr142, isr143, + isr144, isr145, isr146, isr147, isr148, isr149, isr150, isr151, isr152, + isr153, isr154, isr155, isr156, isr157, isr158, isr159, isr160, isr161, + isr162, isr163, isr164, isr165, isr166, isr167, isr168, isr169, isr170, + isr171, isr172, isr173, isr174, isr175, isr176, isr177, isr178, isr179, + isr180, isr181, isr182, isr183, isr184, isr185, isr186, isr187, isr188, + isr189, isr190, isr191, isr192, isr193, isr194, isr195, isr196, isr197, + isr198, isr199, isr200, isr201, isr202, isr203, isr204, isr205, isr206, + isr207, isr208, isr209, isr210, isr211, isr212, isr213, isr214, isr215, + isr216, isr217, isr218, isr219, isr220, isr221, isr222, isr223, isr224, + isr225, isr226, isr227, isr228, isr229, isr230, isr231, isr232, isr233, + isr234, isr235, isr236, isr237, isr238, isr239, isr240, isr241, isr242, + isr243, isr244, isr245, isr246, isr247, isr248, isr249, isr250, isr251, + isr252, isr253, isr254, isr255, +}; + +void (*list_of_handlers[256])(reg_t *); + +void int_handler(reg_t *r) { + list_of_handlers[r->int_no](r); +} + +void install_handler(void (*handler_function)(), u16 type_attribute, u8 entry) { + format_descriptor((u32)isr_list[entry], KERNEL_CODE_SEGMENT_OFFSET, + type_attribute, &IDT_Entry[entry]); + list_of_handlers[entry] = handler_function; +} + void idt_init(void) { + // list_of_handlers = kcalloc(sizeof(void *), 128); + memset(list_of_handlers, 0, sizeof(void *) * 256); + install_handler(page_fault, INT_32_INTERRUPT_GATE(0x0), 0xE); install_handler(double_fault, INT_32_INTERRUPT_GATE(0x0), 0x8); install_handler(general_protection_fault, INT_32_INTERRUPT_GATE(0x0), 0xD); diff --git a/kernel/cpu/idt.h b/kernel/cpu/idt.h index fdd6a3e..9cb6e4d 100644 --- a/kernel/cpu/idt.h +++ b/kernel/cpu/idt.h @@ -54,10 +54,271 @@ typedef struct registers registers_t; struct interrupt_frame; -struct registers { - uintptr_t error_code; - uintptr_t eip, cs, eflags, esp, ss; -} __attribute__((packed)); +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 isr32(); +void isr33(); +void isr34(); +void isr35(); +void isr36(); +void isr37(); +void isr38(); +void isr39(); +void isr40(); +void isr41(); +void isr42(); +void isr43(); +void isr44(); +void isr45(); +void isr46(); +void isr47(); +void isr48(); +void isr49(); +void isr50(); +void isr51(); +void isr52(); +void isr53(); +void isr54(); +void isr55(); +void isr56(); +void isr57(); +void isr58(); +void isr59(); +void isr60(); +void isr61(); +void isr62(); +void isr63(); +void isr64(); +void isr65(); +void isr66(); +void isr67(); +void isr68(); +void isr69(); +void isr70(); +void isr71(); +void isr72(); +void isr73(); +void isr74(); +void isr75(); +void isr76(); +void isr77(); +void isr78(); +void isr79(); +void isr80(); +void isr81(); +void isr82(); +void isr83(); +void isr84(); +void isr85(); +void isr86(); +void isr87(); +void isr88(); +void isr89(); +void isr90(); +void isr91(); +void isr92(); +void isr93(); +void isr94(); +void isr95(); +void isr96(); +void isr97(); +void isr98(); +void isr99(); +void isr100(); +void isr101(); +void isr102(); +void isr103(); +void isr104(); +void isr105(); +void isr106(); +void isr107(); +void isr108(); +void isr109(); +void isr110(); +void isr111(); +void isr112(); +void isr113(); +void isr114(); +void isr115(); +void isr116(); +void isr117(); +void isr118(); +void isr119(); +void isr120(); +void isr121(); +void isr122(); +void isr123(); +void isr124(); +void isr125(); +void isr126(); +void isr127(); +void isr128(); +void isr129(); +void isr130(); +void isr131(); +void isr132(); +void isr133(); +void isr134(); +void isr135(); +void isr136(); +void isr137(); +void isr138(); +void isr139(); +void isr140(); +void isr141(); +void isr142(); +void isr143(); +void isr144(); +void isr145(); +void isr146(); +void isr147(); +void isr148(); +void isr149(); +void isr150(); +void isr151(); +void isr152(); +void isr153(); +void isr154(); +void isr155(); +void isr156(); +void isr157(); +void isr158(); +void isr159(); +void isr160(); +void isr161(); +void isr162(); +void isr163(); +void isr164(); +void isr165(); +void isr166(); +void isr167(); +void isr168(); +void isr169(); +void isr170(); +void isr171(); +void isr172(); +void isr173(); +void isr174(); +void isr175(); +void isr176(); +void isr177(); +void isr178(); +void isr179(); +void isr180(); +void isr181(); +void isr182(); +void isr183(); +void isr184(); +void isr185(); +void isr186(); +void isr187(); +void isr188(); +void isr189(); +void isr190(); +void isr191(); +void isr192(); +void isr193(); +void isr194(); +void isr195(); +void isr196(); +void isr197(); +void isr198(); +void isr199(); +void isr200(); +void isr201(); +void isr202(); +void isr203(); +void isr204(); +void isr205(); +void isr206(); +void isr207(); +void isr208(); +void isr209(); +void isr210(); +void isr211(); +void isr212(); +void isr213(); +void isr214(); +void isr215(); +void isr216(); +void isr217(); +void isr218(); +void isr219(); +void isr220(); +void isr221(); +void isr222(); +void isr223(); +void isr224(); +void isr225(); +void isr226(); +void isr227(); +void isr228(); +void isr229(); +void isr230(); +void isr231(); +void isr232(); +void isr233(); +void isr234(); +void isr235(); +void isr236(); +void isr237(); +void isr238(); +void isr239(); +void isr240(); +void isr241(); +void isr242(); +void isr243(); +void isr244(); +void isr245(); +void isr246(); +void isr247(); +void isr248(); +void isr249(); +void isr250(); +void isr251(); +void isr252(); +void isr253(); +void isr254(); +void isr255(); + +typedef struct reg { + u32 ds; + // Pushed by pusha. + u32 edi, esi, ebp, esp, ebx, edx, ecx, eax; + u32 int_no, error_code; + // Pushed by the processor automatically. + u32 eip, cs, eflags, useresp, ss; +} reg_t; void idt_init(void); __attribute__((no_caller_saved_registers)) void EOI(unsigned char irq); diff --git a/kernel/cpu/int_syscall.s b/kernel/cpu/int_syscall.s deleted file mode 100644 index ec7693a..0000000 --- a/kernel/cpu/int_syscall.s +++ /dev/null @@ -1,21 +0,0 @@ -.intel_syntax noprefix -.global int_syscall -.extern syscall_function_handler -int_syscall: - push esp - push ebp - push edi - push esi - push edx - push ecx - push ebx - push eax - call syscall_function_handler - add esp, 8 - pop ebx - pop ecx - pop edx - pop esi - pop edi - pop ebp - iretd diff --git a/kernel/cpu/syscall.c b/kernel/cpu/syscall.c index 072351d..9b93a4d 100644 --- a/kernel/cpu/syscall.c +++ b/kernel/cpu/syscall.c @@ -6,12 +6,12 @@ #include <errno.h> #include <fs/tmpfs.h> #include <fs/vfs.h> +#include <interrupts.h> #include <kmalloc.h> #include <network/ethernet.h> #include <string.h> #include <syscalls.h> #include <typedefs.h> -#include <interrupts.h> #pragma GCC diagnostic ignored "-Wpedantic" @@ -126,7 +126,7 @@ int syscall_openpty(SYS_OPENPTY_PARAMS *args) { args->winp); } -void (*syscall_functions[])() = { +int (*syscall_functions[])() = { (void(*))syscall_open, (void(*))syscall_read, (void(*))syscall_write, @@ -177,14 +177,15 @@ void (*syscall_functions[])() = { void syscall_function_handler(u32 eax, u32 arg1, u32 arg2, u32 arg3, u32 arg4, u32 arg5, u32 ebp, u32 esp) { - if (esp <= 0x90000000) { - get_current_task()->useresp = esp; - } assert(eax < sizeof(syscall_functions) / sizeof(syscall_functions[0])); syscall_functions[eax](arg1, arg2, arg3, arg4, arg5); } -extern void int_syscall(void); +void int_syscall(reg_t *r) { + u32 syscall = r->eax; + assert(syscall < sizeof(syscall_functions) / sizeof(syscall_functions[0])); + r->eax = syscall_functions[syscall](r->ebx, r->ecx, r->edx, r->esi, r->edi); +} void syscalls_init(void) { install_handler(int_syscall, INT_32_INTERRUPT_GATE(0x3), 0x80); |