From 8b2d35594d746df23b0b5cd02dfd59a84c964f8e Mon Sep 17 00:00:00 2001 From: Starnakin Date: Wed, 2 Oct 2024 14:15:57 +0200 Subject: [PATCH] add: idt --- headers/idt.h | 13 +++++++++- src/interrupt/handler.c | 2 ++ src/interrupt/idt.c | 55 +++++++++++++++++++++++++++++------------ src/interrupt/isr.s | 2 ++ src/kernel.c | 10 ++------ 5 files changed, 57 insertions(+), 25 deletions(-) diff --git a/headers/idt.h b/headers/idt.h index 3159b1b..0d20d92 100644 --- a/headers/idt.h +++ b/headers/idt.h @@ -6,4 +6,15 @@ struct idt_descriptor { uint32_t offset; } __attribute__((packed)); -#define IDT_SIZE 256 \ No newline at end of file +struct idt_entry { + uint16_t isr_low; // The lower 16 bits of the ISR's address + uint16_t kernel_cs; // The GDT segment selector that the CPU will load + // into CS before calling the ISR + uint8_t reserved; // Set to zero + uint8_t attributes; // Type and attributes; see the IDT page + uint16_t isr_high; // The higher 16 bits of the ISR's address +} __attribute__((packed)); + +#define IDT_SIZE 256 + +void init_idt(void); \ No newline at end of file diff --git a/src/interrupt/handler.c b/src/interrupt/handler.c index aeb95d7..b2b241a 100644 --- a/src/interrupt/handler.c +++ b/src/interrupt/handler.c @@ -3,6 +3,8 @@ #include +__attribute__((noreturn)) void exception_handler(void); + void exception_handler(void) { int8_t index = -1; diff --git a/src/interrupt/idt.c b/src/interrupt/idt.c index 781a9da..4c04959 100644 --- a/src/interrupt/idt.c +++ b/src/interrupt/idt.c @@ -1,36 +1,59 @@ #include #include +#include "gdt.h" #include "idt.h" -uint16_t idt_entries[IDT_SIZE * 4]; -struct idt_descriptor idtr; +extern void *isr_stub_table[]; +__attribute__((aligned(0x10))) static struct idt_entry idt_entries[IDT_SIZE]; +static struct idt_descriptor idtr; +/* static void set_idt_entry_value(uint16_t *target, uint32_t offset, uint16_t selector, uint8_t dpl, uint8_t gate_type) { - // Encode the offset - target[0] = offset & 0xFFFF; - target[3] = (offset >> 16) & 0xFFFF; + // Encode the offset + target[0] = offset & 0xFFFF; // Low 16 bits + target[3] = (offset >> 16) & 0xFFFF; // High 16 bits - // Encode the presence - target[1] |= 1 << 15; + // Encode the presence (bit 15) + target[1] |= 1 << 15; - // Encode the CPU Privilege Levels - target[1] = (0b11 << 13) & dpl; + // Encode the CPU Privilege Levels (DPL) + target[1] &= ~(0b11 << 13); // Clear previous DPL + target[1] |= (dpl & 0b11) << 13; // Set new DPL - target[1] &= ~(1 << 12); + // Clear bit 12 (always 0 for interrupts) + target[1] &= ~(1 << 12); - // Encode Gate Type - target[1] |= gate_type & 0x0F00; + // Encode Gate Type + target[1] &= ~0x0F00; // Clear previous gate type + target[1] |= (gate_type & 0x0F) << 8; // Set new gate type - // Encode selector - target[2] = selector; + // Encode selector + target[2] = selector; +}*/ + +void idt_set_descriptor(uint8_t index, void *isr, uint8_t flags) +{ + struct idt_entry *descriptor = &idt_entries[index]; + + descriptor->isr_low = (uint32_t)isr & 0xFFFF; + descriptor->kernel_cs = GDT_OFFSET_KERNEL_CODE; + descriptor->attributes = flags; + descriptor->isr_high = (uint32_t)isr >> 16; + descriptor->reserved = 0; } void init_idt(void) { - idtr.size = 8 * IDT_SIZE - 1; - idtr.offset = (uint32_t)&idt_entries; + idtr.offset = (uintptr_t)&idt_entries[0]; + idtr.size = (uint16_t)sizeof(struct idt_entry) * IDT_SIZE - 1; + + 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"); } diff --git a/src/interrupt/isr.s b/src/interrupt/isr.s index 6d82c1a..3bc2ea6 100644 --- a/src/interrupt/isr.s +++ b/src/interrupt/isr.s @@ -3,12 +3,14 @@ .macro isr_err_stub nb isr_stub_\nb: + movb bl, \nb call exception_handler iret .endm .macro isr_no_err_stub nb isr_stub_\nb: + movb bl, \nb call exception_handler iret .endm diff --git a/src/kernel.c b/src/kernel.c index 618f008..cb3a31b 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -1,5 +1,6 @@ #include "alloc.h" #include "gdt.h" +#include "idt.h" #include "kpanic.h" #include "kprintf.h" #include "memory.h" @@ -27,13 +28,6 @@ void kernel_main(void) terminal_initialize(); init_gdt(); init_memory(); - kprintf(KERN_CRIT "KERN_CRIT\n"); - kprintf(KERN_ALERT "KERN_ALERT\n"); - kprintf(KERN_WARNING "KERN_WARNING\n"); - kprintf(KERN_NOTICE "KERN_NOTICE\n"); - kprintf(KERN_INFO "KERN_INFO\n"); - kprintf(KERN_DEBUG "KERN_DEBUG\n"); - void *ptr = vmalloc(100); - kprintf("%d\n", ksize(ptr)); + init_idt(); shell_init(); }