]> git.dujemihanovic.xyz Git - nameless-os.git/commitdiff
Use interrupt frame and new double fault handler
authorDuje Mihanović <duje.mihanovic@skole.hr>
Tue, 14 Jun 2022 09:23:08 +0000 (11:23 +0200)
committerDuje Mihanović <duje.mihanovic@skole.hr>
Mon, 27 Jun 2022 20:02:00 +0000 (22:02 +0200)
kernel/arch/x86/irq/interrupt.c
kernel/arch/x86/irq/stub.s
kernel/include/arch/x86/irq/idt.h
kernel/include/arch/x86/irq/interrupt.h
kernel/kernel.c

index b2abef97a08c956bce052cfe5c1635a4a1d72b3b..f7cbcdcce60622ddf2ac2b85283b59a6bdc84e7d 100644 (file)
@@ -5,16 +5,17 @@
 #include <irq/i8259a.h>
 
 /* This table will hold pointers to our interrupt handlers. */
-static int (*int_handler_table[256])(void);
+static int (*int_handler_table[256])(struct interrupt_frame *);
 
-void int_handler(int interrupt)
+void int_handler(struct interrupt_frame *frame)
 {
+       int interrupt = frame->interrupt;
        if (int_handler_table[interrupt] == NULL) {
                kprint("WARNING: Unhandled interrupt ", 0);
                kprintb(interrupt);
                kprint(" occurred!\n", 0);
        } else {
-               int ret = (*int_handler_table[interrupt])();
+               int ret = (*int_handler_table[interrupt])(frame);
                if (ret) {
                        kprint("WARNING: Error while handling interrupt ", 0);
                        kprintb(interrupt);
@@ -26,7 +27,7 @@ void int_handler(int interrupt)
        }
 }
 
-int register_interrupt(int irq, int (*handler)(void))
+int register_interrupt(int irq, int (*handler)(struct interrupt_frame *))
 {
        int_handler_table[irq] = handler;
        if (irq >= 32 && irq < 48) {
index c15969a143d3b7909df8195583c055ac5bf77843..e5e43e522b2183c265cb9532dc19d9f5b74843e0 100644 (file)
@@ -7,24 +7,77 @@ extern int_handler
 
 int_common:
        cld
+       push esp
        call int_handler
-       add esp, 4
+       add esp, 12
        popad
        iretd
 
 %macro INTERRUPT 1
-global int%1
+global int_%1
 int_%1:
+       push dword 0
        pushad
        push dword %1
        jmp int_common
 %endmacro
 
-%assign i 0
-%rep 48
-INTERRUPT i
-%assign i i+1
-%endrep
+%macro INTERRUPT_ERR 1
+global int_%1
+int_%1:
+       pushad
+       push dword %1
+       jmp int_common
+%endmacro
+
+INTERRUPT 0
+INTERRUPT 1
+INTERRUPT 2
+INTERRUPT 3
+INTERRUPT 4
+INTERRUPT 5
+INTERRUPT 6
+INTERRUPT 7
+INTERRUPT_ERR 8
+INTERRUPT 9
+INTERRUPT_ERR 10
+INTERRUPT_ERR 11
+INTERRUPT_ERR 12
+INTERRUPT_ERR 13
+INTERRUPT_ERR 14
+INTERRUPT 15
+INTERRUPT 16
+INTERRUPT_ERR 17
+INTERRUPT 18
+INTERRUPT 19
+INTERRUPT 20
+INTERRUPT_ERR 21
+INTERRUPT 22
+INTERRUPT 23
+INTERRUPT 24
+INTERRUPT 25
+INTERRUPT 26
+INTERRUPT 27
+INTERRUPT 28
+INTERRUPT_ERR 29
+INTERRUPT_ERR 30
+INTERRUPT 31
+INTERRUPT 32
+INTERRUPT 33
+INTERRUPT 34
+INTERRUPT 35
+INTERRUPT 36
+INTERRUPT 37
+INTERRUPT 38
+INTERRUPT 39
+INTERRUPT 40
+INTERRUPT 41
+INTERRUPT 42
+INTERRUPT 43
+INTERRUPT 44
+INTERRUPT 45
+INTERRUPT 46
+INTERRUPT 47
 
 ; Define flat table containing addresses of handlers
 section .rodata
index 501e5cd52034b544cbb085f5c71be4784186a599..f16cf9672124c3b5a14afd4a97ab07d4aca92194 100644 (file)
@@ -2,6 +2,7 @@
 #define X86_IDT_H
 
 #include <stdint.h>
+#include <irq/interrupt.h>
 
 #define IDT_VECTOR_COUNT 256 /* our IDT will have 256 vectors */
 #define IDT_DESCRIPTOR_SIZE 8 /* each IDT descriptor is 8 bytes long */
index fbecdd8c4cf086caff3737ebb91953e5b0f0b61d..f43b28c494e1fbb4e73e7106e6158cb74e65c4c8 100644 (file)
@@ -1,6 +1,22 @@
 #ifndef X86_INTERRUPT_H
 #define X86_INTERRUPT_H
 
-extern int register_interrupt(int irq, int (*handler)(void));
+struct interrupt_frame {
+       int interrupt;
+       int edi;
+       int esi;
+       int ebp;
+       int esp; /* before pushad */
+       int ebx;
+       int edx;
+       int ecx;
+       int eax;
+       int err_code;
+       int eip;
+       int cs;
+       int eflags;
+};
+
+extern int register_interrupt(int irq, int (*handler)(struct interrupt_frame *));
 
 #endif
index 5a6a82d1d75b816e9efdee7eb3c7d3e151d4bdcf..85209067926874a079863992b26de801e4a9bdca 100644 (file)
@@ -34,6 +34,48 @@ void print_e820(struct e820_map *mmap, int mmap_size)
        }
 }
 
+/* Small handler for double faults. Will be put elsewhere eventually. */
+int double_fault_handler(struct interrupt_frame *frame)
+{
+       kprint("PANIC: Double fault occurred!\n", VGA_COLOR_BRIGHT_RED);
+       kprint("EAX: ", VGA_COLOR_BRIGHT_RED);
+       kprintd(frame->eax);
+       kprint("\n", VGA_COLOR_BRIGHT_RED);
+       kprint("EBX: ", VGA_COLOR_BRIGHT_RED);
+       kprintd(frame->ebx);
+       kprint("\n", VGA_COLOR_BRIGHT_RED);
+       kprint("ECX: ", VGA_COLOR_BRIGHT_RED);
+       kprintd(frame->ecx);
+       kprint("\n", VGA_COLOR_BRIGHT_RED);
+       kprint("EDX: ", VGA_COLOR_BRIGHT_RED);
+       kprintd(frame->edx);
+       kprint("\n", VGA_COLOR_BRIGHT_RED);
+       kprint("EBP: ", VGA_COLOR_BRIGHT_RED);
+       kprintd(frame->ebp);
+       kprint("\n", VGA_COLOR_BRIGHT_RED);
+       kprint("ESP: ", VGA_COLOR_BRIGHT_RED);
+       kprintd(frame->esp);
+       kprint("\n", VGA_COLOR_BRIGHT_RED);
+       kprint("ESI: ", VGA_COLOR_BRIGHT_RED);
+       kprintd(frame->esi);
+       kprint("\n", VGA_COLOR_BRIGHT_RED);
+       kprint("EDI: ", VGA_COLOR_BRIGHT_RED);
+       kprintd(frame->edi);
+       kprint("\n", VGA_COLOR_BRIGHT_RED);
+       kprint("EIP: ", VGA_COLOR_BRIGHT_RED);
+       kprintd(frame->eip);
+       kprint("\n", VGA_COLOR_BRIGHT_RED);
+       kprint("EFLAGS: ", VGA_COLOR_BRIGHT_RED);
+       kprintd(frame->eflags);
+       kprint("\n", VGA_COLOR_BRIGHT_RED);
+
+       /* IF has already been cleared for us */
+       asm("cli");
+halt:
+       asm("hlt");
+       goto halt;
+}
+
 void kmain(struct e820_map *mmap, int mmap_size)
 {
        screen_clear();
@@ -50,6 +92,7 @@ void kmain(struct e820_map *mmap, int mmap_size)
        populate_idtr(&idtr, idt);
        load_idt(idtr);
        kprint("Setting up interrupts...\n", 0);
+       register_interrupt(8, &double_fault_handler);
        pic_init(0x20, 0x28);
        pic_mask_all();
        asm volatile ("sti");