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}