idt.c

Commit: d8432d7b Author: jokerz Raw Copy
1
/* ============================================================================
2
 * Pactor64 — IDT + PIC Initialization (x86-64)
3
 * 256-entry IDT, PIC remapping to IRQ 0x20-0x2F, interrupt dispatch
4
 * ============================================================================ */
5
#include "../include/pactor64.h"
6
7
/* === IDT Data === */
8
static struct idt_entry idt[256];
9
static struct idtr       idtr_reg;
10
11
/* === Interrupt handler table === */
12
typedef void (*irq_handler_t)(registers_t *regs);
13
static irq_handler_t irq_handlers[256];
14
15
/* === Set a single IDT entry === */
16
static void idt_set_entry(int index, uint64_t handler, uint16_t sel, uint8_t flags) {
17
    idt[index].offset_low  = handler & 0xFFFF;
18
    idt[index].offset_mid  = (handler >> 16) & 0xFFFF;
19
    idt[index].offset_high = (handler >> 32) & 0xFFFFFFFF;
20
    idt[index].selector    = sel;
21
    idt[index].ist         = 0;
22
    idt[index].type_attr   = flags;
23
    idt[index].reserved    = 0;
24
}
25
26
/* === PIC Remap === */
27
void pic_remap(int offset1, int offset2) {
28
    /* ICW1: begin init, expect ICW4 */
29
    outb(PIC1_CMD,  0x11); io_wait();
30
    outb(PIC2_CMD,  0x11); io_wait();
31
32
    /* ICW2: vector offsets */
33
    outb(PIC1_DATA, offset1); io_wait();
34
    outb(PIC2_DATA, offset2); io_wait();
35
36
    /* ICW3: master has slave on IR2, slave is cascade identity 2 */
37
    outb(PIC1_DATA, 0x04); io_wait();
38
    outb(PIC2_DATA, 0x02); io_wait();
39
40
    /* ICW4: 8086 mode */
41
    outb(PIC1_DATA, 0x01); io_wait();
42
    outb(PIC2_DATA, 0x01); io_wait();
43
44
    /* Mask all IRQs */
45
    outb(PIC1_DATA, 0xFF);
46
    outb(PIC2_DATA, 0xFF);
47
}
48
49
void pic_mask_all(void) {
50
    outb(PIC1_DATA, 0xFF);
51
    outb(PIC2_DATA, 0xFF);
52
}
53
54
void pic_unmask_irq(int irq) {
55
    uint16_t port;
56
    if (irq < 8) {
57
        port = PIC1_DATA;
58
    } else {
59
        port = PIC2_DATA;
60
        irq -= 8;
61
    }
62
    uint8_t mask = inb(port) & ~(1 << irq);
63
    outb(port, mask);
64
}
65
66
void pic_send_eoi(int irq) {
67
    if (irq >= 8) {
68
        outb(PIC2_CMD, PIC_EOI);
69
    }
70
    outb(PIC1_CMD, PIC_EOI);
71
}
72
73
/* === Install an IRQ handler === */
74
void irq_install(int irq, irq_handler_t handler) {
75
    irq_handlers[irq] = handler;
76
}
77
78
/* === Interrupt Dispatch (called from isr_common in asm) === */
79
void isr_dispatch(registers_t *regs) {
80
    uint64_t int_no = regs->int_no;
81
82
    /* Call registered handler if any */
83
    if (irq_handlers[int_no]) {
84
        irq_handlers[int_no](regs);
85
    } else if (int_no < 32) {
86
        /* Unhandled CPU exception */
87
        kprintf("\n  [EXCEPTION] Interrupt %d, Error: %d\n", int_no, regs->err_code);
88
        kprintf("  RIP=%x CS=%x RFLAGS=%x\n", regs->rip, regs->cs, regs->rflags);
89
    if (int_no == 14) {
90
        uint64_t cr2; __asm__ volatile("mov %%cr2, %0" : "=r"(cr2));
91
        kprintf("  CR2 (fault addr)=%x\n", cr2);
92
    }
93
        kprintf("  RAX=%x RBX=%x RCX=%x RDX=%x\n", regs->rax, regs->rbx, regs->rcx, regs->rdx);
94
        kprintf("  RSP=%x RBP=%x\n", regs->rsp, regs->rbp);
95
        kprintf("  System halted.\n");
96
        cli();
97
        hlt();
98
        for (;;) hlt();
99
    }
100
101
    /* Send EOI for hardware IRQs (0x20-0x2F) */
102
    if (int_no >= 0x20 && int_no <= 0x2F) {
103
        pic_send_eoi(int_no - 0x20);
104
    }
105
}
106
107
/* === Initialize the full 256-entry IDT === */
108
void idt_init(void) {
109
    /* Zero the IDT */
110
    kmemset(idt, 0, sizeof(idt));
111
112
    /* Populate all 256 entries from the assembly stub table */
113
    for (int i = 0; i < 256; i++) {
114
        idt_set_entry(i, isr_stub_table[i], 0x08, 0x8E);
115
        /* 0x08 = kernel code segment selector
116
         * 0x8E = Present, DPL=0, 64-bit interrupt gate */
117
    }
118
119
    /* Load IDTR */
120
    idtr_reg.limit = sizeof(idt) - 1;
121
    idtr_reg.base  = (uint64_t)&idt;
122
    idt_load(&idtr_reg);
123
}
124