diff --git a/headers/interrupts.h b/headers/interrupts.h index e469d48..8c5939b 100644 --- a/headers/interrupts.h +++ b/headers/interrupts.h @@ -1,3 +1,6 @@ #pragma once +#include + void exception_handler(void); +void pic_send_eoi(uint8_t irq); diff --git a/src/interrupt/handler.c b/src/interrupt/handler.c index 0bb0aa0..94b2d07 100644 --- a/src/interrupt/handler.c +++ b/src/interrupt/handler.c @@ -4,6 +4,7 @@ #include "utils.h" #include +#define NTMFDP 0 const char *faults[] = { "division by zero", @@ -46,3 +47,12 @@ void exception_handler(void) } kprintf(KERN_ERR "interrupt triggered with no matching code\n"); } + +void irq_handler(void) +{ + int8_t index = -1; + __asm__ volatile("movb %%bl, %0" ::"m"(index)); + + pic_send_eoi(NTMFDP); + kpanic("cramptés\n"); +} diff --git a/src/interrupt/idt.c b/src/interrupt/idt.c index a5aac00..7ddac7a 100644 --- a/src/interrupt/idt.c +++ b/src/interrupt/idt.c @@ -14,10 +14,13 @@ #define PIC2_DATA (PIC2 + 1) extern void *isr_stub_table[]; +extern void *irq_stub_table[]; __attribute__((aligned(0x10))) static struct idt_entry idt_entries[IDT_SIZE]; static struct idt_descriptor idtr; +void load_idt(struct idt_descriptor *idtr); + void idt_set_descriptor(uint8_t index, void *isr, uint8_t flags) { struct idt_entry *descriptor = &idt_entries[index]; @@ -36,8 +39,9 @@ void init_idt(void) for (uint8_t i = 0; i < 32; i++) idt_set_descriptor(i, isr_stub_table[i], 0x8E); - __asm__ volatile("lidt %0" : : "m"(idtr)); - __asm__ volatile("sti"); + for (uint8_t i = 32; i < 48; i++) + idt_set_descriptor(i, irq_stub_table[i], 0x8E); + load_idt(&idtr); // https://wiki.osdev.org/8259_PIC#Programming_with_the_8259_PIC pic_remap(0x20, 0x28); pic_disable(); diff --git a/src/interrupt/irq.s b/src/interrupt/irq.s new file mode 100644 index 0000000..3d5f3ea --- /dev/null +++ b/src/interrupt/irq.s @@ -0,0 +1,45 @@ +.intel_syntax noprefix +.extern irq_handler + +.macro irq_common_stub nb +irq_stub_\nb: + mov bl, \nb + call irq_handler + iret +.endm + +irq_common_stub 0 +irq_common_stub 1 +irq_common_stub 2 +irq_common_stub 3 +irq_common_stub 4 +irq_common_stub 5 +irq_common_stub 6 +irq_common_stub 7 +irq_common_stub 8 +irq_common_stub 9 +irq_common_stub 10 +irq_common_stub 11 +irq_common_stub 12 +irq_common_stub 13 +irq_common_stub 14 +irq_common_stub 15 + +.global irq_stub_table +irq_stub_table: + .long irq_stub_0 + .long irq_stub_1 + .long irq_stub_2 + .long irq_stub_3 + .long irq_stub_4 + .long irq_stub_5 + .long irq_stub_6 + .long irq_stub_7 + .long irq_stub_8 + .long irq_stub_9 + .long irq_stub_10 + .long irq_stub_11 + .long irq_stub_12 + .long irq_stub_13 + .long irq_stub_14 + .long irq_stub_15 diff --git a/src/interrupt/load_idt.s b/src/interrupt/load_idt.s new file mode 100644 index 0000000..a2d299c --- /dev/null +++ b/src/interrupt/load_idt.s @@ -0,0 +1,11 @@ +.intel_syntax noprefix + +.global load_idt +load_idt: +push ebp +mov ebp, esp +mov eax, [ebp + 8] +lidt [eax] +mov esp, ebp +pop ebp +ret diff --git a/src/interrupt/pic.c b/src/interrupt/pic.c index 3ef7254..b5bce4f 100644 --- a/src/interrupt/pic.c +++ b/src/interrupt/pic.c @@ -20,6 +20,8 @@ #define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */ #define ICW4_SFNM 0x10 /* Special fully nested (not) */ +#define PIC_EOI 0x20 /* End-of-interrupt command code */ + void pic_remap(int offset_master, int offset_slave) { uint8_t a1, a2; @@ -59,3 +61,10 @@ void pic_disable(void) outb(PIC1_DATA, 0xff); outb(PIC2_DATA, 0xff); } + +void pic_send_eoi(uint8_t irq) +{ + if (irq >= 8) + outb(PIC2_COMMAND, PIC_EOI); + outb(PIC1_COMMAND, PIC_EOI); +} diff --git a/src/kernel.c b/src/kernel.c index cf59a47..44496cb 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -1,11 +1,9 @@ -#include "alloc.h" #include "gdt.h" #include "idt.h" -#include "kpanic.h" #include "kprintf.h" #include "memory.h" +#include "power.h" #include "shell.h" -#include "string.h" #include "terminal.h" #include