1#include "idt.h"
2#include "io.h"
3
4struct idt_entry idt[256] __attribute__((aligned(16)));
5struct idt_ptr idtp;
6
7// Function defined in interrupts.asm
8extern void load_idt(uint32_t idt_ptr);
9
10void set_idt_gate(int n, uint32_t handler) {
11 idt[n].base_low = handler & 0xFFFF;
12 idt[n].selector = 0x08; // This matches CODE_SEG offset in GDT
13 idt[n].zero = 0;
14 idt[n].flags = 0x8E; // Present, Ring 0, Interrupt Gate
15 idt[n].base_high = (handler >> 16) & 0xFFFF;
16}
17
18void remap_pic() {
19 // ICW1
20 outb(0x20, 0x11);
21 outb(0xA0, 0x11);
22
23 // ICW2 (Offsets)
24 outb(0x21, 0x20); // Master PIC starts at 0x20
25 outb(0xA1, 0x28); // Slave PIC starts at 0x28
26
27 // ICW3 (Cascade)
28 outb(0x21, 0x04);
29 outb(0xA1, 0x02);
30
31 // ICW4 (8086 mode)
32 outb(0x21, 0x01);
33 outb(0xA1, 0x01);
34
35 // Unmask only Keyboard (IRQ 1)
36 outb(0x21, 0xFD);
37 outb(0xA1, 0xFF);
38}
39
40extern void exception_handler_stub();
41
42void init_idt() {
43 // Zero out the IDT
44 for (int i = 0; i < 256; i++) {
45 idt[i].base_low = 0;
46 idt[i].selector = 0x08;
47 idt[i].zero = 0;
48 idt[i].flags = 0x8E;
49 idt[i].base_high = 0;
50 set_idt_gate(i, (uint32_t)exception_handler_stub);
51 }
52
53 idtp.limit = (sizeof(struct idt_entry) * 256) - 1;
54 idtp.base = (uint32_t)&idt;
55
56 remap_pic();
57 load_idt((uint32_t)&idtp);
58}