summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2024-02-09 14:08:28 +0100
committerAnton Kling <anton@kling.gg>2024-02-09 14:08:28 +0100
commita8ffc46136eb16adc87fb520c724467d1295a854 (patch)
tree2d1758a4e3c5b6ef8430c5a6b1aca7249ef7a56d /kernel
parent581ac7e072633f68deed5c5d343603c053895907 (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/Makefile2
-rw-r--r--kernel/cpu/idt.c60
-rw-r--r--kernel/cpu/idt.h269
-rw-r--r--kernel/cpu/int_syscall.s21
-rw-r--r--kernel/cpu/syscall.c13
-rw-r--r--kernel/drivers/keyboard.c5
-rw-r--r--kernel/drivers/mouse.c6
-rw-r--r--kernel/drivers/pit.c10
-rw-r--r--kernel/drivers/rtl8139.c2
-rw-r--r--kernel/init/kernel.c2
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);
}
}