Code: Select all
#ifndef IDT_H_INCLUDED
#define IDT_H_INCLUDED
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include "../byte.h"
#include "../itoa.h"
#include "../terminal.h"
#define IDT_MAX_DESCRIPTORS 256
#define KEYBOARD_DATA_PORT 0x60
#define PIC1_COMMAND_PORT 0x20
#define PIC1_DATA_PORT 0x21
#define PIC_EOI 0x20
typedef struct {
uint16_t isr_low;
uint16_t kernel_cs;
uint8_t ist;
uint8_t attributes;
uint16_t isr_mid;
uint32_t isr_high;
uint32_t reserved;
} __attribute__((packed)) idt_entry_t;
__attribute__((aligned(0x10)))
static idt_entry_t idt[IDT_MAX_DESCRIPTORS];
typedef struct {
uint16_t limit;
uint64_t base;
} __attribute__((packed)) idtr_t;
static idtr_t idtr;
static bool vectors[IDT_MAX_DESCRIPTORS];
__attribute__((noreturn))
void exception_handler(void) {
terminal_write("An exception occured\n");
__asm__ volatile ("cli; hlt");
}
void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags) {
idt_entry_t* descriptor = &idt[vector];
descriptor->isr_low = (uint64_t)isr & 0xFFFF;
descriptor->kernel_cs = 0x100000;
descriptor->ist = 0;
descriptor->attributes = flags;
descriptor->isr_mid = ((uint64_t)isr >> 16) & 0xFFFF;
descriptor->isr_high = ((uint64_t)isr >> 32) & 0xFFFFFFFF;
descriptor->reserved = 0;
}
extern void* isr_stub_table[];
void keyboard_interrupt_handler() {
uint8_t scancode = inb(KEYBOARD_DATA_PORT);
outb(PIC1_COMMAND_PORT, PIC_EOI);
char str[100];
terminal_write("Key pressed: ");
terminal_write(itoa(scancode, str, 10));
}
void keyboard_init() {
outb(PIC1_DATA_PORT, inb(PIC1_DATA_PORT) & ~(1 << 1));
uint16_t mask = inb(PIC1_DATA_PORT) & ~(1 << 1);
outb(PIC1_DATA_PORT, mask);
idt_set_descriptor(33, keyboard_interrupt_handler, 0x8E);
terminal_write("Keyboard: Initialized\n");
}
void idt_init(void) {
idtr.base = (uintptr_t)&idt[0];
idtr.limit = (uint16_t)sizeof(idt_entry_t) * IDT_MAX_DESCRIPTORS - 1;
for (uint8_t vector = 0; vector < 32; vector++) {
idt_set_descriptor(vector, isr_stub_table[vector], 0x8E);
vectors[vector] = true;
}
__asm__ volatile ("lidt %0" : : "m"(idtr));
__asm__ volatile ("sti");
terminal_write("IDT: Initialized\n");
}
#endif