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 | |
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')
-rw-r--r-- | kernel/Makefile | 2 | ||||
-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 | ||||
-rw-r--r-- | kernel/drivers/keyboard.c | 5 | ||||
-rw-r--r-- | kernel/drivers/mouse.c | 6 | ||||
-rw-r--r-- | kernel/drivers/pit.c | 10 | ||||
-rw-r--r-- | kernel/drivers/rtl8139.c | 2 | ||||
-rw-r--r-- | kernel/init/kernel.c | 2 |
10 files changed, 334 insertions, 56 deletions
diff --git a/kernel/Makefile b/kernel/Makefile index f2d1fdb..c9fffe6 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -1,6 +1,6 @@ CC="i686-sb-gcc" AS="i686-sb-as" -OBJ = arch/i386/boot.o init/kernel.o cpu/gdt.o cpu/reload_gdt.o cpu/idt.o cpu/io.o libc/stdio/print.o drivers/keyboard.o log.o drivers/pit.o libc/string/memcpy.o libc/string/strlen.o libc/string/memcmp.o drivers/ata.o libc/string/memset.o cpu/syscall.o read_eip.o libc/exit/assert.o process.o cpu/int_syscall.o libc/string/strcpy.o arch/i386/mmu.o kmalloc.o fs/ext2.o fs/vfs.o fs/devfs.o cpu/spinlock.o random.o libc/string/strcmp.o crypto/ChaCha20/chacha20.o crypto/SHA1/sha1.o fs/tmpfs.o libc/string/isequal.o drivers/pst.o halts.o syscalls/ppoll.o syscalls/ftruncate.o kubsan.o syscalls/mmap.o drivers/serial.o syscalls/accept.o syscalls/bind.o syscalls/socket.o socket.o poll.o fs/fifo.o hashmap/hashmap.o fs/shm.o syscalls/shm.o elf.o ksbrk.o sched/scheduler.o syscalls/stat.o libc/string/copy.o libc/string/strncpy.o drivers/mouse.o libc/string/strlcpy.o libc/string/strcat.o drivers/vbe.o syscalls/msleep.o syscalls/uptime.o syscalls/mkdir.o drivers/pci.o drivers/rtl8139.o network/ethernet.o network/arp.o network/bytes.o network/ipv4.o network/udp.o syscalls/recvfrom.o math.o syscalls/sendto.o signal.o syscalls/kill.o syscalls/sigaction.o network/tcp.o drivers/ahci.o crypto/xoshiro256plusplus/xoshiro256plusplus.o syscalls/chdir.o syscalls/getcwd.o syscalls/isatty.o syscalls/randomfill.o syscalls/open.o syscalls/write.o syscalls/pwrite.o ipc.o syscalls/ipc.o syscalls/port.o syscalls/map_frames.o syscalls/virtual_to_physical.o syscalls/install_irq.o switch_task.o arch/i386/interrupts.o +OBJ = arch/i386/boot.o init/kernel.o cpu/gdt.o cpu/reload_gdt.o cpu/idt.o cpu/io.o libc/stdio/print.o drivers/keyboard.o log.o drivers/pit.o libc/string/memcpy.o libc/string/strlen.o libc/string/memcmp.o drivers/ata.o libc/string/memset.o cpu/syscall.o read_eip.o libc/exit/assert.o process.o libc/string/strcpy.o arch/i386/mmu.o kmalloc.o fs/ext2.o fs/vfs.o fs/devfs.o cpu/spinlock.o random.o libc/string/strcmp.o crypto/ChaCha20/chacha20.o crypto/SHA1/sha1.o fs/tmpfs.o libc/string/isequal.o drivers/pst.o halts.o syscalls/ppoll.o syscalls/ftruncate.o kubsan.o syscalls/mmap.o drivers/serial.o syscalls/accept.o syscalls/bind.o syscalls/socket.o socket.o poll.o fs/fifo.o hashmap/hashmap.o fs/shm.o syscalls/shm.o elf.o ksbrk.o sched/scheduler.o syscalls/stat.o libc/string/copy.o libc/string/strncpy.o drivers/mouse.o libc/string/strlcpy.o libc/string/strcat.o drivers/vbe.o syscalls/msleep.o syscalls/uptime.o syscalls/mkdir.o drivers/pci.o drivers/rtl8139.o network/ethernet.o network/arp.o network/bytes.o network/ipv4.o network/udp.o syscalls/recvfrom.o math.o syscalls/sendto.o signal.o syscalls/kill.o syscalls/sigaction.o network/tcp.o drivers/ahci.o crypto/xoshiro256plusplus/xoshiro256plusplus.o syscalls/chdir.o syscalls/getcwd.o syscalls/isatty.o syscalls/randomfill.o syscalls/open.o syscalls/write.o syscalls/pwrite.o ipc.o syscalls/ipc.o syscalls/port.o syscalls/map_frames.o syscalls/virtual_to_physical.o syscalls/install_irq.o switch_task.o arch/i386/interrupts.o cpu/isr.o CFLAGS = -O0 -fsanitize=vla-bound,shift-exponent,pointer-overflow,shift,signed-integer-overflow,bounds -ggdb -ffreestanding -Wall -Werror -mgeneral-regs-only -Wimplicit-fallthrough -I./libc/include/ -I. -Wno-pointer-sign -DKERNEL #LDFLAGS=-flto -Ofast LDFLAGS= 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); diff --git a/kernel/drivers/keyboard.c b/kernel/drivers/keyboard.c index 0e3edf8..f59e6a8 100644 --- a/kernel/drivers/keyboard.c +++ b/kernel/drivers/keyboard.c @@ -1,4 +1,5 @@ #include <assert.h> +#include <cpu/idt.h> #include <drivers/keyboard.h> #include <errno.h> #include <fs/devfs.h> @@ -107,8 +108,8 @@ struct KEY_EVENT { }; extern process_t *ready_queue; -__attribute__((interrupt)) void -int_keyboard(__attribute__((unused)) struct interrupt_frame *frame) { + +void int_keyboard(reg_t *frame) { outb(0x20, 0x20); u16 c; c = inb(PS2_REG_DATA); diff --git a/kernel/drivers/mouse.c b/kernel/drivers/mouse.c index 884b024..067f335 100644 --- a/kernel/drivers/mouse.c +++ b/kernel/drivers/mouse.c @@ -3,8 +3,8 @@ #include <fs/devfs.h> #include <fs/fifo.h> #include <fs/vfs.h> -#include <typedefs.h> #include <interrupts.h> +#include <typedefs.h> u8 mouse_cycle = 0; // unsigned char u8 mouse_u8[3]; // signed char @@ -45,11 +45,11 @@ void add_mouse(void) { get_current_task()->file_descriptors[fd] = NULL; } -__attribute__((interrupt)) void what(registers_t *r) { +void what(registers_t *r) { EOI(0xe); } -__attribute__((interrupt)) void int_mouse(registers_t *r) { +void int_mouse(reg_t *r) { (void)r; EOI(12); switch (mouse_cycle) { diff --git a/kernel/drivers/pit.c b/kernel/drivers/pit.c index 8f9c35c..509f3f5 100644 --- a/kernel/drivers/pit.c +++ b/kernel/drivers/pit.c @@ -41,15 +41,7 @@ void set_pit_count(u16 hertz) { outb(PIT_IO_CHANNEL_0, (divisor & 0xFF00) >> 8); } -__attribute__((interrupt)) void int_clock(registers_t *regs) { - process_t *p = get_current_task(); - if (p) { - // FIXME: For some reason eflags is the esp? I have read the - // manual multilpe times and still can't figure out why. - if (regs->eflags <= 0x90000000 && regs->eflags) { - p->useresp = regs->eflags; - } - } +void int_clock(reg_t regs) { outb(0x20, 0x20); pit_counter++; if (pit_counter >= hertz / 1000) { diff --git a/kernel/drivers/rtl8139.c b/kernel/drivers/rtl8139.c index b07ccef..6e738db 100644 --- a/kernel/drivers/rtl8139.c +++ b/kernel/drivers/rtl8139.c @@ -90,7 +90,7 @@ void handle_packet(void) { } } -__attribute__((interrupt)) void rtl8139_handler(void *regs) { +void rtl8139_handler(void *regs) { (void)regs; u16 status = inw(rtl8139.gen.base_mem_io + 0x3e); diff --git a/kernel/init/kernel.c b/kernel/init/kernel.c index e829ce3..4a14216 100644 --- a/kernel/init/kernel.c +++ b/kernel/init/kernel.c @@ -107,7 +107,7 @@ void kernel_main(u32 kernel_end, unsigned long magic, unsigned long addr, } } for (;;) { - enable_interrupts(); + asm("sti"); switch_task(0); } } |