diff options
| author | Carlos Maiolino <[email protected]> | 2025-07-26 15:32:32 +0200 |
|---|---|---|
| committer | Carlos Maiolino <[email protected]> | 2025-08-01 13:07:38 +0200 |
| commit | 57d8e2b236c7a185bdd941c247ef0dcc5961a24e (patch) | |
| tree | 1d1f496510c77422647f1513c3ca6f85e0110689 /src | |
| parent | 80ac430366d65ef89a078832380a021308bbbfdf (diff) | |
Implement interrupt descriptor table
Signed-off-by: Carlos Maiolino <[email protected]>
Diffstat (limited to 'src')
| -rw-r--r-- | src/idt/idt.asm | 13 | ||||
| -rw-r--r-- | src/idt/idt.c | 42 | ||||
| -rw-r--r-- | src/include/toxic/idt.h | 27 | ||||
| -rw-r--r-- | src/kernel.c | 2 |
4 files changed, 84 insertions, 0 deletions
diff --git a/src/idt/idt.asm b/src/idt/idt.asm new file mode 100644 index 0000000..998a242 --- /dev/null +++ b/src/idt/idt.asm @@ -0,0 +1,13 @@ +section .asm + +global idt_load: + +idt_load: + push ebp + mov ebp, esp + + mov ebx, [ebp + 8] + lidt [ebx] + + pop ebp + ret diff --git a/src/idt/idt.c b/src/idt/idt.c new file mode 100644 index 0000000..d7a6743 --- /dev/null +++ b/src/idt/idt.c @@ -0,0 +1,42 @@ +#include <stdint.h> +#include <toxic/config.h> +#include <toxic/string.h> +#include <toxic/vga.h> +#include <toxic/idt.h> + +struct int_descriptor int_table[TOTAL_INTERRUPTS]; +struct int_reg_descriptor idtr_descriptor; + +extern void idt_load(struct int_reg_descriptor *desc); + +static void +idt_zero() +{ + vprintl("Illegal operation: Divide by zero\n"); +} + +static void +idt_set(int int_num, void *addr) +{ + struct int_descriptor *desc = &int_table[int_num]; + + desc->offset_low = (uint32_t) addr & 0x0000FFFF; + desc->selector = KERNEL_CODE_SELECTOR; + desc->reserved = 0x00; + desc->type_attr = TOXIC_INT_ATTR; + desc->offset_high = (uint32_t) addr >> 16; +} + +void +interrupts_init(void) +{ + memset(int_table, 0, sizeof(int_table)); + + idtr_descriptor.limit = sizeof(int_table) - 1; + idtr_descriptor.base = (uint32_t) int_table; + + idt_set(0, idt_zero); + + idt_load(&idtr_descriptor); +} + diff --git a/src/include/toxic/idt.h b/src/include/toxic/idt.h new file mode 100644 index 0000000..f54f7f7 --- /dev/null +++ b/src/include/toxic/idt.h @@ -0,0 +1,27 @@ +#ifndef IDT_H +#define IDT_H +#include <stdint.h> + +/* ATTR byte field values */ +#define INT_GATE_32 0x0E +#define TRAP_GATE_32 0x0F +#define DPL_RING3 0x60 +#define PRESENT_BIT (1 << 7) + +#define TOXIC_INT_ATTR (PRESENT_BIT | DPL_RING3 | INT_GATE_32) + +struct int_descriptor { + uint16_t offset_low; /* bits 0..15 */ + uint16_t selector; /* Code segment selector */ + uint8_t reserved; /* Unused, must be 0 */ + uint8_t type_attr; /* gate type, DPL, presence */ + uint16_t offset_high; /* bits 16..31 */ +} __attribute__((packed)); + +struct int_reg_descriptor { + uint16_t limit; /* Int descriptor table size (bytes) -1 */ + uint32_t base; /* Table starting offset (linear address) */ +} __attribute__((packed)); + +void interrupts_init(void); +#endif /* IDT_H */ diff --git a/src/kernel.c b/src/kernel.c index 0aa8eef..c2a0150 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -3,10 +3,12 @@ #include <toxic/vga.h> #include <toxic/string.h> #include <toxic/kernel.h> +#include <toxic/idt.h> void start_kernel() { init_display(2); vprintl("Hello World!!!\n"); + interrupts_init(); } |
